30 using System.Collections.Generic;
31 using System.Reflection;
32 using System.Threading;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Client;
40 using OpenSim.Framework.Monitoring;
41 using OpenSim.Region.Framework.Interfaces;
43 using OpenSim.Region.Framework.Scenes.Types;
44 using OpenSim.Region.PhysicsModules.SharedBase;
46 using OpenSim.Services.Interfaces;
49 namespace OpenSim.
Region.Framework.Scenes
79 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
80 private static readonly
String LogHeader =
"[SCENE PRESENCE]";
90 m_scene.EventManager.TriggerScenePresenceUpdated(
this);
93 public bool isNPC {
get;
private set; }
97 get {
return m_presenceType;}
100 m_presenceType = value;
101 isNPC = (m_presenceType == PresenceType.Npc);
105 private ScenePresenceStateMachine m_stateMachine;
115 return m_stateMachine.GetState();
120 m_stateMachine.SetState(value);
132 private object m_completeMovementLock =
new object();
135 private static readonly
Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
136 private static readonly Vector3 HEAD_ADJUSTMENT =
new Vector3(0f, 0f, 0.3f);
146 public static readonly Vector3 SIT_TARGET_ADJUSTMENT =
new Vector3(0.0f, 0.0f, 0.4f);
147 public bool LegacySitOffsets =
true;
155 public static readonly
float MOVEMENT = .25f;
156 public static readonly
float SIGNIFICANT_MOVEMENT = 16.0f;
157 public static readonly
float CHILDUPDATES_MOVEMENT = 100.0f;
158 public static readonly
float CHILDUPDATES_TIME = 10000f;
160 private UUID m_previusParcelUUID = UUID.Zero;
161 private UUID m_currentParcelUUID = UUID.Zero;
162 private bool m_previusParcelHide =
false;
163 private bool m_currentParcelHide =
false;
164 private object parcelLock =
new Object();
166 public UUID currentParcelUUID
168 get {
return m_currentParcelUUID; }
173 bool oldhide = m_currentParcelHide;
174 bool checksame =
true;
175 if (value != m_currentParcelUUID)
177 m_previusParcelHide = m_currentParcelHide;
178 m_previusParcelUUID = m_currentParcelUUID;
181 m_currentParcelUUID = value;
182 m_currentParcelHide =
false;
184 ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
186 m_currentParcelHide =
true;
188 if (m_previusParcelUUID !=
UUID.Zero || checksame)
189 ParcelCrossCheck(m_currentParcelUUID,m_previusParcelUUID,m_currentParcelHide, m_previusParcelHide, oldhide,checksame);
212 public bool ParcelAllowThisAvatarSounds
220 ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
227 return land.LandData.GroupID == ControllingClient.ActiveGroupId;
237 public bool ParcelHideThisAvatar
241 return m_currentParcelHide;
262 private List<SceneObjectGroup> m_attachments =
new List<SceneObjectGroup>();
264 public Object AttachmentsSyncLock {
get;
private set; }
266 private Dictionary<UUID, ScriptControllers> scriptedcontrols =
new Dictionary<UUID, ScriptControllers>();
269 private bool MouseDown =
false;
276 private Vector3 m_lastPosition;
277 private Quaternion m_lastRotation;
278 private Vector3 m_lastVelocity;
279 private Vector3 m_lastSize =
new Vector3(0.45f,0.6f,1.9f);
281 private bool m_followCamAuto =
false;
283 private Vector3? m_forceToApply;
284 private int m_userFlags;
287 get {
return m_userFlags; }
293 get {
return PhysicsActor != null && PhysicsActor.Flying; }
294 set { PhysicsActor.Flying = value; }
297 public bool IsColliding
299 get {
return PhysicsActor != null && PhysicsActor.IsColliding; }
301 set { PhysicsActor.IsColliding = value; }
307 private List<uint> m_lastColliders =
new List<uint>();
312 get {
return m_teleportFlags; }
313 set { m_teleportFlags = value; }
316 private uint m_requestedSitTargetID;
317 private UUID m_requestedSitTargetUUID;
322 public bool SitGround {
get;
private set; }
328 private Vector3 m_LastFinitePos;
330 private float m_sitAvatarHeight = 2.0f;
332 private bool childUpdatesBusy =
false;
333 private int lastChildUpdatesTime;
334 private Vector3 m_lastChildAgentUpdatePosition;
337 private const int LAND_VELOCITYMAG_MAX = 12;
339 private const float FLY_ROLL_MAX_RADIANS = 1.1f;
341 private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f;
342 private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
344 private float m_health = 100f;
348 private readonly Vector3[] Dir_Vectors =
new Vector3[12];
354 private Quaternion m_headrotation = Quaternion.Identity;
357 public bool MovingToTarget {
get;
private set; }
358 public Vector3 MoveToPositionTarget {
get;
private set; }
363 public bool LandAtTarget {
get;
private set; }
365 private int m_movementUpdateCount;
366 private const int NumMovementsBetweenRayCast = 5;
368 private bool CameraConstraintActive;
373 private object m_collisionEventLock =
new Object();
375 private int m_movementAnimationUpdateCounter = 0;
377 public Vector3 PrevSitOffset {
get; set; }
383 get {
return m_appearance; }
386 m_appearance = value;
396 public List<string> InTransitScriptStates
398 get {
return m_InTransitScriptStates; }
399 private set { m_InTransitScriptStates = value; }
401 private List<string> m_InTransitScriptStates =
new List<string>();
406 private enum Dir_ControlFlags:uint
408 DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
409 DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
410 DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
411 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
412 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
413 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
414 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
415 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
416 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
417 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
418 DIR_CONTROL_FLAG_UP_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS,
419 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
425 private Vector3 posLastSignificantMove;
426 private Vector3 posLastMove;
428 #region For teleports and crossings callbacks
433 private string m_callbackURI;
442 private UUID m_originRegionID;
449 private object m_originRegionIDAccessLock =
new object();
456 public bool DoNotCloseAfterTeleport {
get; set; }
475 public uint MovementFlag {
get;
private set; }
480 public bool AgentControlStopActive {
get;
private set; }
482 private bool m_invulnerable =
true;
484 public bool Invulnerable
486 set { m_invulnerable = value; }
487 get {
return m_invulnerable; }
490 private int m_userLevel;
494 get {
return m_userLevel; }
495 private set { m_userLevel = value; }
498 private int m_godLevel;
502 get {
return m_godLevel; }
503 private set { m_godLevel = value; }
506 private ulong m_rootRegionHandle;
507 private Vector3 m_rootRegionPosition =
new Vector3();
509 public ulong RegionHandle
511 get {
return m_rootRegionHandle; }
514 m_rootRegionHandle = value;
516 m_rootRegionPosition.X = (float)((m_rootRegionHandle >> 32) & 0xffffff00);
517 m_rootRegionPosition.Y = (float)(m_rootRegionHandle & 0xffffff00);
521 #region Client Camera
528 private Vector4 m_lastCameraCollisionPlane =
new Vector4(0f, 0f, 0f, 1);
529 private bool m_doingCamRayCast =
false;
531 public Vector3 CameraPosition {
get; set; }
533 public Quaternion CameraRotation
535 get {
return Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis); }
541 public Vector3 CameraAtAxis {
get; set; }
542 public Vector3 CameraLeftAxis {
get; set; }
543 public Vector3 CameraUpAxis {
get; set; }
545 public Vector3 Lookat
549 Vector3 a =
new Vector3(CameraAtAxis.X, CameraAtAxis.Y, 0);
556 public string Firstname {
get;
private set; }
557 public string Lastname {
get;
private set; }
559 public string Grouptitle
561 get {
return UseFakeGroupTitle ?
"(Loading)" : m_groupTitle; }
562 set { m_groupTitle = value; }
564 private string m_groupTitle;
570 public bool UseFakeGroupTitle {
get; set; }
573 private float m_drawDistance = 255f;
574 public float DrawDistance
578 return m_drawDistance;
582 m_drawDistance = Util.Clamp(value, 32f, m_scene.MaxDrawDistance);
586 public float RegionViewDistance
590 return Util.Clamp(m_drawDistance, 32f, m_scene.MaxRegionViewDistance);
594 public bool AllowMovement {
get; set; }
596 private bool m_setAlwaysRun;
608 return m_setAlwaysRun;
613 m_setAlwaysRun = value;
616 PhysicsActor.SetAlwaysRun = value;
622 public byte State {
get; set; }
624 private AgentManager.ControlFlags m_AgentControlFlags;
626 public uint AgentControlFlags
628 get {
return (uint)m_AgentControlFlags; }
629 set { m_AgentControlFlags = (AgentManager.ControlFlags)value; }
646 public override Vector3 AbsolutePosition
652 m_pos = PhysicsActor.Position;
674 if (ParentPart != null)
679 if (rootPart != null)
680 return rootPart.AbsolutePosition + (m_pos * rootPart.GetWorldRotation());
695 PhysicsActor.Position = value;
699 m_log.Error(
"[SCENE PRESENCE]: ABSOLUTE POSITION " + e.Message);
710 TriggerScenePresenceUpdated();
718 public Vector3 OffsetPosition
720 get {
return m_pos; }
730 TriggerScenePresenceUpdated();
743 m_velocity = PhysicsActor.Velocity;
759 PhysicsActor.TargetVelocity = value;
763 m_log.Error(
"[SCENE PRESENCE]: VELOCITY " + e.Message);
775 private Quaternion m_bodyRot = Quaternion.Identity;
800 PhysicsActor.Orientation = m_bodyRot;
804 m_log.Error(
"[SCENE PRESENCE]: Orientation " + e.Message);
812 private Vector3 m_AngularVelocity = Vector3.Zero;
816 get {
return m_AngularVelocity; }
819 public bool IsChildAgent {
get; set; }
820 public bool IsLoggingIn {
get; set; }
827 public UUID ParentUUID
829 get {
return m_parentUUID; }
830 set { m_parentUUID = value; }
832 private UUID m_parentUUID = UUID.Zero;
838 public bool IsSatOnObject {
get {
return ParentID != 0; } }
850 get {
return m_health; }
851 set { m_health = value; }
868 return sitPart.GetWorldRotation() *
Rotation;
882 return sitPart.ParentGroup.Velocity;
889 Dictionary<ulong, string> seeds;
892 seeds = Scene.CapsModule.GetChildrenSeeds(
UUID);
894 seeds =
new Dictionary<ulong, string>();
913 KnownRegions = seeds;
920 m_log.Info(
"================ KnownRegions "+Scene.RegionInfo.RegionName+
" ================");
921 foreach (KeyValuePair<ulong, string> kvp
in KnownRegions)
924 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
925 m_log.Info(
" >> "+x+
", "+y+
": "+kvp.Value);
929 private bool m_mouseLook;
930 private bool m_leftButtonDown;
932 private bool m_inTransit;
940 public bool IsInTransit
942 get {
return m_inTransit; }
947 m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY;
949 m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY;
962 private const float AgentControlStopSlowVel = 0.2f;
964 public const float AgentControlNudgeVel = 1.0f;
965 public const float AgentControlNormalVel = 1.0f;
969 private float m_speedModifier = 1.0f;
971 public float SpeedModifier
973 get {
return m_speedModifier; }
974 set { m_speedModifier = value; }
977 private bool m_forceFly;
981 get {
return m_forceFly; }
982 set { m_forceFly = value; }
985 private bool m_flyDisabled;
987 public bool FlyDisabled
989 get {
return m_flyDisabled; }
990 set { m_flyDisabled = value; }
995 get {
return Util.GetViewerName(m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode)); }
1000 #region Constructor(s)
1006 AttachmentsSyncLock =
new Object();
1007 AllowMovement =
true;
1008 IsChildAgent =
true;
1009 IsLoggingIn =
false;
1010 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
1014 DrawDistance = world.DefaultDrawDistance;
1015 RegionHandle = world.RegionInfo.RegionHandle;
1016 ControllingClient = client;
1017 Firstname = ControllingClient.FirstName;
1018 Lastname = ControllingClient.LastName;
1019 m_name = String.Format(
"{0} {1}", Firstname, Lastname);
1020 m_uuid = client.AgentId;
1021 LocalId = m_scene.AllocateLocalId();
1022 LegacySitOffsets = m_scene.LegacySitOffsets;
1024 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
1025 if (account != null)
1026 m_userFlags = account.UserFlags;
1030 if (account != null)
1031 UserLevel = account.UserLevel;
1035 Grouptitle = gm.GetGroupTitle(m_uuid);
1037 m_scriptEngines = m_scene.RequestModuleInterfaces<
IScriptModule>();
1039 AbsolutePosition = posLastMove = posLastSignificantMove = CameraPosition =
1040 m_reprioritizationLastPosition = ControllingClient.StartPos;
1043 childUpdatesBusy =
true;
1044 m_reprioritizationBusy =
true;
1049 SetDirectionVectors();
1051 Appearance = appearance;
1053 m_stateMachine =
new ScenePresenceStateMachine(
this);
1056 private void RegionHeartbeatEnd(
Scene scene)
1061 m_movementAnimationUpdateCounter ++;
1062 if (m_movementAnimationUpdateCounter >= 2)
1064 m_movementAnimationUpdateCounter = 0;
1065 if (Animator != null)
1073 if(ParentID == 0 && !SitGround && ParentUUID ==
UUID.Zero)
1074 Animator.UpdateMovementAnimations();
1078 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1085 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
1086 ControllingClient.OnAgentUpdate += HandleAgentUpdate;
1087 ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate;
1088 ControllingClient.OnAgentRequestSit += HandleAgentRequestSit;
1089 ControllingClient.OnAgentSit += HandleAgentSit;
1090 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
1091 ControllingClient.OnStartAnim += HandleStartAnim;
1092 ControllingClient.OnStopAnim += HandleStopAnim;
1093 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
1094 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
1095 ControllingClient.OnAutoPilotGo += MoveToTarget;
1096 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
1102 private void SetDirectionVectors()
1104 Dir_Vectors[0] =
new Vector3(AgentControlNormalVel,0,0);
1105 Dir_Vectors[1] =
new Vector3(-AgentControlNormalVel,0,0);;
1106 Dir_Vectors[2] =
new Vector3(0,AgentControlNormalVel,0);
1107 Dir_Vectors[3] =
new Vector3(0,-AgentControlNormalVel,0);
1108 Dir_Vectors[4] =
new Vector3(0,0,AgentControlNormalVel);
1109 Dir_Vectors[5] =
new Vector3(0,0,-AgentControlNormalVel);
1110 Dir_Vectors[6] =
new Vector3(AgentControlNudgeVel, 0f, 0f);
1111 Dir_Vectors[7] =
new Vector3(-AgentControlNudgeVel, 0f, 0f);
1112 Dir_Vectors[8] =
new Vector3(0f, AgentControlNudgeVel, 0f);
1113 Dir_Vectors[9] =
new Vector3(0f, -AgentControlNudgeVel, 0f);
1114 Dir_Vectors[10] =
new Vector3(0f, 0f, AgentControlNudgeVel);
1115 Dir_Vectors[11] =
new Vector3(0f, 0f, -AgentControlNudgeVel);
1119 #region Status Methods
1135 const float PhysSearchHeight = 600f;
1136 const float PhysMinSkipGap = 50f;
1137 const int PhysNumberCollisions = 30;
1141 private bool MakeRootAgent(Vector3 pos,
bool isFlying, ref Vector3 lookat)
1143 int ts = Util.EnvironmentTickCount();
1145 lock (m_completeMovementLock)
1150 m_log.DebugFormat(
"[MakeRootAgent] enter lock: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1157 if (ParentUUID !=
UUID.Zero)
1159 m_log.DebugFormat(
"[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1160 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1163 m_log.ErrorFormat(
"[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1166 PrevSitOffset = Vector3.Zero;
1167 HandleForceReleaseControls(ControllingClient, UUID);
1168 IsLoggingIn =
false;
1172 part.AddSittingAvatar(
this);
1173 if (part.SitTargetPosition != Vector3.Zero)
1174 part.SitTargetAvatar =
UUID;
1177 m_pos = PrevSitOffset;
1178 pos = part.GetWorldPosition();
1180 ParentUUID = UUID.Zero;
1184 IsLoggingIn =
false;
1187 IsChildAgent =
false;
1190 m_log.DebugFormat(
"[MakeRootAgent] out lock: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1199 Grouptitle = gm.GetGroupTitle(m_uuid);
1201 m_log.DebugFormat(
"[MakeRootAgent] Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1203 RegionHandle = m_scene.RegionInfo.RegionHandle;
1205 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
1206 m_log.DebugFormat(
"[MakeRootAgent] TriggerSetRootAgentScene: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1210 bool positionChanged =
false;
1211 if(!CheckAndAdjustLandingPoint(ref pos, ref lookat, ref positionChanged ))
1213 m_log.DebugFormat(
"[SCENE PRESENCE MakeRootAgent]: houston we have a problem.. {0}({1} got here banned",Name,
UUID);
1216 if (pos.X < 0f || pos.Y < 0f
1217 || pos.X >= m_scene.RegionInfo.RegionSizeX
1218 || pos.Y >= m_scene.RegionInfo.RegionSizeY)
1221 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1226 else if(pos.X >= m_scene.RegionInfo.RegionSizeX)
1227 pos.X = m_scene.RegionInfo.RegionSizeX - 0.5f;
1230 else if(pos.Y >= m_scene.RegionInfo.RegionSizeY)
1231 pos.Y = m_scene.RegionInfo.RegionSizeY - 0.5f;
1234 float groundHeight = m_scene.GetGroundHeight(pos.X, pos.Y) + .01f;
1235 float physTestHeight;
1237 if(PhysSearchHeight < groundHeight + 100f)
1238 physTestHeight = groundHeight + 100f;
1240 physTestHeight = PhysSearchHeight;
1242 float localAVHalfHeight = 0.8f;
1243 if (Appearance != null && Appearance.AvatarHeight > 0)
1244 localAVHalfHeight = 0.5f * Appearance.AvatarHeight;
1246 groundHeight += localAVHalfHeight;
1247 if (groundHeight > pos.Z)
1248 pos.Z = groundHeight;
1250 bool checkPhysics = !positionChanged &&
1251 m_scene.SupportsRayCastFiltered() &&
1252 pos.Z < physTestHeight &&
1255 || (m_teleportFlags & TeleportFlags.ViaLocation) != 0
1262 rayfilter |= RayFilterFlags.PrimsNonPhantomAgents;
1264 int physcount = PhysNumberCollisions;
1266 float dist = physTestHeight - groundHeight + localAVHalfHeight;
1268 Vector3 direction =
new Vector3(0f, 0f, -1f);
1269 Vector3 RayStart = pos;
1270 RayStart.Z = physTestHeight;
1272 List<ContactResult> physresults =
1273 (List<ContactResult>)m_scene.RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
1274 if (physresults != null && physresults.Count > 0)
1276 float dest = physresults[0].Pos.Z;
1278 if(physresults.Count > 1)
1282 return a.Depth.CompareTo(b.Depth);
1286 int count = physresults.Count;
1287 float curd = physresults[0].Depth;
1288 float nextd = curd + PhysMinSkipGap;
1289 float maxDepth = dist - pos.Z;
1290 for(
int i = 1; i < count; i++)
1292 curd = physresults[i].Depth;
1296 if(curd >= maxDepth)
1299 nextd = curd + PhysMinSkipGap;
1301 dest = physresults[sel].Pos.Z;
1304 dest += localAVHalfHeight;
1310 AbsolutePosition = pos;
1319 AddToPhysicalScene(isFlying);
1321 PhysicsActor.SetMomentum(vel);
1325 AddToPhysicalScene(isFlying);
1328 CameraPosition = pos;
1335 else if (FlyDisabled)
1342 m_log.DebugFormat(
"[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1343 m_scene.SwapRootAgentCount(
false);
1350 m_scene.EventManager.TriggerOnMakeRootAgent(
this);
1351 m_log.DebugFormat(
"[MakeRootAgent] TriggerOnMakeRootAgent and done: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1356 private void RestartAttachmentScripts()
1371 List<SceneObjectGroup> attachments = GetAttachments();
1374 "[SCENE PRESENCE]: Restarting scripts in {0} attachments for {1} in {2}", attachments.Count, Name, Scene.Name);
1377 foreach (SceneObjectGroup sog
in attachments)
1379 sog.ScheduleGroupForFullUpdate();
1380 sog.RootPart.ParentGroup.CreateScriptInstances(0,
false, m_scene.DefaultScriptEngine, GetStateSource());
1381 sog.ResumeScripts();
1385 private static bool IsRealLogin(
TeleportFlags teleportFlags)
1387 return ((teleportFlags &
TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0);
1446 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1448 RegionHandle = newRegionHandle;
1450 m_log.DebugFormat(
"[SCENE PRESENCE]: Making {0} a child agent in {1} from root region {2}",
1451 Name, Scene.RegionInfo.RegionName, newRegionHandle);
1455 lock (m_originRegionIDAccessLock)
1456 m_originRegionID = UUID.Zero;
1466 if (Animator == null)
1469 Animator.ResetAnimations();
1480 IsChildAgent =
true;
1481 m_scene.SwapRootAgentCount(
true);
1482 RemoveFromPhysicalScene();
1486 m_previusParcelHide =
false;
1487 m_previusParcelUUID = UUID.Zero;
1488 m_currentParcelHide =
false;
1489 m_currentParcelUUID = UUID.Zero;
1494 m_scene.EventManager.TriggerOnMakeChildAgent(
this);
1506 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1507 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1508 PhysicsActor.UnSubscribeEvents();
1526 TeleportWithMomentum(pos, Vector3.Zero);
1531 if(!CheckLocalTPLandingPoint(ref pos))
1537 bool isFlying = Flying;
1539 RemoveFromPhysicalScene();
1541 AbsolutePosition = pos;
1542 AddToPhysicalScene(isFlying);
1546 PhysicsActor.SetMomentum((Vector3)v);
1548 PhysicsActor.SetMomentum(vel);
1551 SendTerseUpdateToAllClients();
1556 if(!CheckLocalTPLandingPoint(ref newpos))
1559 AbsolutePosition = newpos;
1561 if (newvel.HasValue)
1563 if ((Vector3)newvel == Vector3.Zero)
1566 PhysicsActor.SetMomentum(Vector3.Zero);
1567 m_velocity = Vector3.Zero;
1572 PhysicsActor.SetMomentum((Vector3)newvel);
1573 m_velocity = (Vector3)newvel;
1577 Vector3 lookAt = (Vector3)newvel;
1580 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)
TeleportFlags.ViaLocation);
1585 SendTerseUpdateToAllClients();
1593 Vector3 pos = AbsolutePosition;
1594 if (Appearance.AvatarHeight != 127.0f)
1595 pos +=
new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f));
1597 pos +=
new Vector3(0f, 0f, (1.56f / 6f));
1599 AbsolutePosition = pos;
1607 if (Appearance.AvatarHeight != 127.0f)
1608 CollisionPlane =
new Vector4(0, 0, 0, pos.Z - Appearance.AvatarHeight / 6f);
1612 SendAgentTerseUpdate(
this);
1619 private void ApplyFlyingRoll(
float amount,
bool PressingUp,
bool PressingDown)
1622 float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
1623 m_AngularVelocity.Z = rollAmount;
1634 if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f)
1635 m_AngularVelocity.Z -= 0.9f;
1640 if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f)
1641 m_AngularVelocity.Z += 0.6f;
1650 if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS))
1651 m_AngularVelocity.Z += 0.6f;
1656 if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f)
1657 m_AngularVelocity.Z -= 0.6f;
1667 private float CalculateFlyingRollResetToZero(
float amount)
1669 const float rollMinRadians = 0f;
1671 if (m_AngularVelocity.Z > 0)
1674 float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
1675 if (amount > leftOverToMin)
1676 return -leftOverToMin;
1684 float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
1685 if (amount > leftOverToMin)
1686 return leftOverToMin;
1696 private Dictionary<ulong, string> m_knownChildRegions =
new Dictionary<ulong, string>();
1698 struct spRegionSizeInfo
1704 private Dictionary<ulong, spRegionSizeInfo> m_knownChildRegionsSizeInfo =
new Dictionary<ulong, spRegionSizeInfo>();
1709 lock (m_knownChildRegions)
1711 spRegionSizeInfo sizeInfo =
new spRegionSizeInfo();
1712 sizeInfo.sizeX = region.RegionSizeX;
1713 sizeInfo.sizeY = region.RegionSizeY;
1714 ulong regionHandle = region.RegionHandle;
1716 if (!m_knownChildRegionsSizeInfo.ContainsKey(regionHandle))
1718 m_knownChildRegionsSizeInfo.Add(regionHandle, sizeInfo);
1722 m_knownChildRegionsSizeInfo[regionHandle] = sizeInfo;
1728 lock (m_knownChildRegions)
1730 m_knownChildRegionsSizeInfo.Clear();
1733 spRegionSizeInfo sizeInfo =
new spRegionSizeInfo();
1734 sizeInfo.sizeX = region.RegionSizeX;
1735 sizeInfo.sizeY = region.RegionSizeY;
1736 ulong regionHandle = region.RegionHandle;
1737 m_knownChildRegionsSizeInfo.Add(regionHandle, sizeInfo);
1744 lock (m_knownChildRegions)
1750 m_knownChildRegions.Remove(regionHandle);
1751 m_knownChildRegionsSizeInfo.Remove(regionHandle);
1757 foreach (ulong handle
in oldRegions)
1759 RemoveNeighbourRegion(handle);
1760 Scene.CapsModule.DropChildSeed(
UUID, handle);
1766 ulong handle = m_scene.RegionInfo.RegionHandle;
1767 RemoveNeighbourRegion(handle);
1768 Scene.CapsModule.DropChildSeed(
UUID, handle);
1771 public Dictionary<ulong, string> KnownRegions
1775 lock (m_knownChildRegions)
1776 return new Dictionary<ulong, string>(m_knownChildRegions);
1782 lock (m_knownChildRegions)
1783 m_knownChildRegions = value;
1787 public List<ulong> KnownRegionHandles
1791 return new List<ulong>(KnownRegions.Keys);
1795 public int KnownRegionCount
1799 lock (m_knownChildRegions)
1800 return m_knownChildRegions.Count;
1806 #region Event Handlers
1815 PhysicsActor.Size =
new Vector3(0.45f, 0.6f, height);
1818 public void SetSize(Vector3 size,
float feetoffset)
1821 PhysicsActor.setAvatarSize(size, feetoffset);
1824 private bool WaitForUpdateAgent(
IClientAPI client)
1832 UUID originID = UUID.Zero;
1834 lock (m_originRegionIDAccessLock)
1835 originID = m_originRegionID;
1838 while (originID.Equals(UUID.Zero) && count-- > 0)
1840 lock (m_originRegionIDAccessLock)
1841 originID = m_originRegionID;
1843 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting
for update in {1}
", client.Name, Scene.Name);
1847 if (originID.Equals(UUID.Zero))
1849 // Movement into region will fail
1850 m_log.WarnFormat("[SCENE PRESENCE]: Update
agent {0} never arrived in {1}
", client.Name, Scene.Name);
1866 public void CompleteMovement(IClientAPI client, bool openChildAgents)
1868 int ts = Util.EnvironmentTickCount();
1871 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}
",
1872 client.Name, Scene.Name, AbsolutePosition);
1878 // Make sure it's not a login agent. We don't want to wait for updates during login
1879 if (!isNPC && !IsRealLogin(m_teleportFlags))
1882 // Let's wait until UpdateAgent (called by departing region) is done
1883 if (!WaitForUpdateAgent(client))
1884 // The sending region never sent the UpdateAgent data, we have to refuse
1888 m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
1890 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1892 Vector3 look = Lookat;
1893 if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01))
1898 if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01) )
1899 look = new Vector3(0.99f, 0.042f, 0);
1902 if (!MakeRootAgent(AbsolutePosition, flying, ref look))
1905 "[SCENE PRESENCE]: Aborting CompleteMovement call
for {0} in {1} as they are already root
",
1911 m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
1914 // start sending terrain patchs
1916 Scene.SendLayerData(ControllingClient);
1918 if (!IsChildAgent && !isNPC)
1920 InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46);
1926 m_log.DebugFormat("[ScenePresence]: CompleteMovement COF
for {0} is {1}
", client.AgentId, COF);
1929 // Tell the client that we're totally ready
1930 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1932 m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
1934 if (!string.IsNullOrEmpty(m_callbackURI))
1936 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1937 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
1938 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1939 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1940 // region as the current region, meaning that a close sent before then will fail the teleport.
1941 // System.Threading.Thread.Sleep(2000);
1944 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}
",
1945 client.Name, client.AgentId, m_callbackURI);
1949 lock (m_originRegionIDAccessLock)
1950 originID = m_originRegionID;
1952 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
1953 m_callbackURI = null;
1957 // m_log.DebugFormat(
1958 // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}
",
1959 // client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1962 m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
1964 m_previusParcelHide = false;
1965 m_previusParcelUUID = UUID.Zero;
1966 m_currentParcelHide = false;
1967 m_currentParcelUUID = UUID.Zero;
1969 // send initial land overlay and parcel
1970 ILandChannel landch = m_scene.LandChannel;
1972 landch.sendClientInitialLandInfo(client);
1976 // verify baked textures and cache
1977 bool cachedbaked = false;
1983 if (m_scene.AvatarFactory != null)
1984 cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this);
1986 // not sure we need this
1989 if (m_scene.AvatarFactory != null)
1990 m_scene.AvatarFactory.QueueAppearanceSave(UUID);
1994 List<ScenePresence> allpresences = m_scene.GetScenePresences();
1996 // send avatar object to all presences including us, so they cross it into region
1997 // then hide if necessary
1998 SendInitialAvatarDataToAllAgents(allpresences);
2001 SendAppearanceToAgent(this);
2003 // send this animations
2005 UUID[] animIDs = null;
2006 int[] animseqs = null;
2007 UUID[] animsobjs = null;
2009 if (Animator != null)
2010 Animator.GetArrays(out animIDs, out animseqs, out animsobjs);
2012 bool haveAnims = (animIDs != null && animseqs != null && animsobjs != null);
2015 SendAnimPackToAgent(this, animIDs, animseqs, animsobjs);
2017 // we should be able to receive updates, etc
2019 m_inTransit = false;
2021 // send look and animations to others
2022 // if not cached we send greys
2023 // uncomented if will wait till avatar does baking
2026 foreach (ScenePresence p in allpresences)
2031 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
2034 SendAppearanceToAgentNF(p);
2036 SendAnimPackToAgentNF(p, animIDs, animseqs, animsobjs);
2040 m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
2043 if (isNPC || IsRealLogin(m_teleportFlags))
2045 if (Scene.AttachmentsModule != null)
2046 // Util.FireAndForget(
2051 Scene.AttachmentsModule.RezAttachments(this);
2053 Util.FireAndForget(x =>
2055 Scene.AttachmentsModule.RezAttachments(this);
2062 if (m_attachments.Count > 0)
2065 "[SCENE PRESENCE]: Restarting scripts in attachments
for {0} in {1}
", Name, Scene.Name);
2067 foreach (SceneObjectGroup sog in m_attachments)
2069 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
2070 sog.ResumeScripts();
2073 foreach (ScenePresence p in allpresences)
2077 SendAttachmentsToAgentNF(this);
2081 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
2084 SendAttachmentsToAgentNF(p);
2089 m_log.DebugFormat("[CompleteMovement] attachments: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
2090 if (openChildAgents)
2092 // Create child agents in neighbouring regions
2093 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
2094 if (m_agentTransfer != null)
2096 m_agentTransfer.EnableChildAgents(this);
2098 // let updates be sent, with some delay
2099 lastChildUpdatesTime = Util.EnvironmentTickCount() + 10000;
2100 childUpdatesBusy = false; // allow them
2104 m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
2106 // send the rest of the world
2107 if (m_teleportFlags > 0 && !isNPC || m_currentParcelHide)
2108 SendInitialDataToMe();
2110 // priority uses avatar position only
2111 m_reprioritizationLastPosition = AbsolutePosition;
2112 m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
2113 m_reprioritizationBusy = false;
2115 m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
2117 if (!IsChildAgent && openChildAgents)
2119 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
2120 if (friendsModule != null)
2121 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
2123 m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
2129 m_inTransit = false;
2131 // if hide force a check
2132 // if (!IsChildAgent && newhide)
2134 // ParcelLoginCheck(m_currentParcelUUID);
2135 // m_currentParcelHide = newhide;
2138 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
2140 m_log.DebugFormat("[CompleteMovement] end: {0}ms
", Util.EnvironmentTickCountSubtract(ts));
2153 private void UpdateCameraCollisionPlane(Vector4 plane)
2155 if (m_lastCameraCollisionPlane != plane)
2157 m_lastCameraCollisionPlane = plane;
2158 ControllingClient.SendCameraConstraint(plane);
2162 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
2164 const float POSITION_TOLERANCE = 0.02f;
2165 const float ROTATION_TOLERANCE = 0.02f;
2167 m_doingCamRayCast = false;
2168 if (hitYN && localid != LocalId)
2170 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
2171 bool IsPrim = group != null;
2174 SceneObjectPart part = group.GetPart(localid);
2175 if (part != null && !part.VolumeDetectActive)
2177 CameraConstraintActive = true;
2178 pNormal.X = (float) Math.Round(pNormal.X, 2);
2179 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
2180 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
2181 pNormal.Normalize();
2182 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
2183 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
2184 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
2186 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
2187 Vector3.Dot(collisionPoint, pNormal));
2188 UpdateCameraCollisionPlane(plane);
2193 CameraConstraintActive = true;
2194 pNormal.X = (float) Math.Round(pNormal.X, 2);
2195 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
2196 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
2197 pNormal.Normalize();
2198 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
2199 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
2200 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
2202 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
2203 Vector3.Dot(collisionPoint, pNormal));
2204 UpdateCameraCollisionPlane(plane);
2207 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2208 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
2210 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
2211 UpdateCameraCollisionPlane(plane);
2212 CameraConstraintActive = false;
2219 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
2221 // m_log.DebugFormat(
2222 // "[SCENE PRESENCE]: In {0} received
agent update from {1}, flags {2}
",
2223 // Scene.Name, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
2227 // m_log.DebugFormat("DEBUG: HandleAgentUpdate: child
agent in {0}
", Scene.Name);
2234 #region Sanity Checking
2236 // This is irritating. Really.
2237 if (!AbsolutePosition.IsFinite())
2239 RemoveFromPhysicalScene();
2240 m_log.Error("[AVATAR]: NonFinite
Avatar position detected... Reset Position. Mantis
this please. Error #9999902
");
2242 m_pos = m_LastFinitePos;
2243 if (!m_pos.IsFinite())
2248 m_log.Error("[AVATAR]: NonFinite
Avatar position detected... Reset Position. Mantis
this please. Error #9999903
");
2251 AddToPhysicalScene(false);
2255 m_LastFinitePos = m_pos;
2258 #endregion Sanity Checking
2262 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
2264 // The Agent's Draw distance setting
2265 // When we get to the point of re-computing neighbors everytime this
2266 // changes, then start using the agent's drawdistance rather than the
2267 // region's draw distance.
2269 DrawDistance = agentData.Far;
2271 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
2273 // FIXME: This does not work as intended because the viewer only sends the lbutton down when the button
2274 // is first pressed, not whilst it is held down. If this is required in the future then need to look
2275 // for an AGENT_CONTROL_LBUTTON_UP event and make sure to handle cases where an initial DOWN is not
2276 // received (e.g. on holding LMB down on the avatar in a viewer).
2277 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
2281 // // Make anims work for client side autopilot
2282 // if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
2283 // m_updateCount = UPDATE_COUNT;
2285 // // Make turning in place work
2286 // if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0 ||
2287 // (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
2288 // m_updateCount = UPDATE_COUNT;
2291 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
2296 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
2297 // this exclude checks may not be complete
2299 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
2301 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
2303 Vector3 posAdjusted = AbsolutePosition;
2304 // posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
2305 posAdjusted.Z += 1.0f; // viewer current camera focus point
2306 Vector3 tocam = CameraPosition - posAdjusted;
2307 tocam.X = (float)Math.Round(tocam.X, 1);
2308 tocam.Y = (float)Math.Round(tocam.Y, 1);
2309 tocam.Z = (float)Math.Round(tocam.Z, 1);
2311 float distTocamlen = tocam.Length();
2312 if (distTocamlen > 0.3f)
2314 tocam *= (1.0f / distTocamlen);
2315 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
2316 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
2317 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
2319 m_doingCamRayCast = true;
2320 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
2323 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
2325 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
2326 UpdateCameraCollisionPlane(plane);
2327 CameraConstraintActive = false;
2331 uint flagsForScripts = (uint)flags;
2332 flags = RemoveIgnoredControls(flags, IgnoredControls);
2334 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
2335 HandleAgentSitOnGround();
2337 // In the future, these values might need to go global.
2338 // Here's where you get them.
2339 m_AgentControlFlags = flags;
2340 m_headrotation = agentData.HeadRotation;
2341 byte oldState = State;
2342 State = agentData.State;
2344 // We need to send this back to the client in order to stop the edit beams
2345 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
2346 SendAgentTerseUpdate(this);
2348 PhysicsActor actor = PhysicsActor;
2350 // This will be the case if the agent is sitting on the groudn or on an object.
2353 SendControlsToScripts(flagsForScripts);
2357 if (AllowMovement && !SitGround)
2359 // m_log.DebugFormat("[SCENE PRESENCE]: Initial body
rotation {0}
for {1}
", agentData.BodyRotation, Name);
2360 bool update_rotation = false;
2361 if (agentData.BodyRotation != Rotation)
2363 Rotation = agentData.BodyRotation;
2364 update_rotation = true;
2367 bool update_movementflag = false;
2369 if (agentData.UseClientAgentPosition)
2371 MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
2372 MoveToPositionTarget = agentData.ClientAgentPosition;
2376 bool DCFlagKeyPressed = false;
2377 Vector3 agent_control_v3 = Vector3.Zero;
2379 bool newFlying = false;
2383 else if (FlyDisabled)
2386 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
2388 if (actor.Flying != newFlying)
2390 // Note: ScenePresence.Flying is actually fetched from the physical actor
2391 // so setting PhysActor.Flying here also sets the ScenePresence's value.
2392 actor.Flying = newFlying;
2393 update_movementflag = true;
2398 bool bAllowUpdateMoveToPosition = false;
2400 Vector3[] dirVectors;
2402 // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
2403 // this prevents 'jumping' in inappropriate situations.
2404 // if (!Flying && (m_mouseLook || m_leftButtonDown))
2405 // dirVectors = GetWalkDirectionVectors();
2407 dirVectors = Dir_Vectors;
2409 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
2410 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
2412 if (((uint)flags & (uint)DCF) != 0)
2414 DCFlagKeyPressed = true;
2418 agent_control_v3 += Dir_Vectors[i];
2419 //m_log.DebugFormat("[Motion]: {0}, {1}
",i, dirVectors[i]);
2421 catch (IndexOutOfRangeException)
2423 // Why did I get this?
2426 if (((MovementFlag & (uint)DCF) == 0))
2428 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag
for {0} with {1}
", Name, DCF);
2429 MovementFlag |= (uint)DCF;
2430 update_movementflag = true;
2435 if ((MovementFlag & (uint)DCF) != 0)
2437 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag
for {0} with lack of {1}
", Name, DCF);
2438 MovementFlag &= (uint)~DCF;
2439 update_movementflag = true;
2442 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
2443 && ((MovementFlag & (byte)nudgehack) == nudgehack))
2445 m_log.Debug("Removed Hack flag
");
2451 bAllowUpdateMoveToPosition = true;
2458 // Detect AGENT_CONTROL_STOP state changes
2459 if (AgentControlStopActive != ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STOP) != 0))
2461 AgentControlStopActive = !AgentControlStopActive;
2462 update_movementflag = true;
2467 // If the user has pressed a key then we want to cancel any move to target.
2468 if (DCFlagKeyPressed)
2470 ResetMoveToTarget();
2471 update_movementflag = true;
2473 else if (bAllowUpdateMoveToPosition)
2475 // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
2476 // certain position. It's only check for tolerance on returning to that position is 0.2
2477 // rather than 1, at which point it removes its force target.
2478 if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2f : 1f, ref agent_control_v3))
2479 update_movementflag = true;
2484 // Cause the avatar to stop flying if it's colliding
2485 // with something with the down arrow pressed.
2487 // Only do this if we're flying
2488 if (Flying && !ForceFly)
2490 // Need to stop in mid air if user holds down AGENT_CONTROL_STOP
2491 // if (AgentControlStopActive)
2493 // agent_control_v3 = Vector3.Zero;
2497 // Landing detection code
2499 // Are the landing controls requirements filled?
2500 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
2501 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2503 //m_log.Debug("[CONTROL]:
" +flags);
2504 // Applies a satisfying roll effect to the avatar when flying.
2505 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
2508 FLY_ROLL_RADIANS_PER_UPDATE,
2509 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
2510 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
2512 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
2513 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
2516 -FLY_ROLL_RADIANS_PER_UPDATE,
2517 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
2518 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
2522 if (m_AngularVelocity.Z != 0)
2523 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
2527 if (Flying && IsColliding && controlland)
2529 // nesting this check because LengthSquared() is expensive and we don't
2530 // want to do it every step when flying.
2531 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
2537 else if (IsColliding && agent_control_v3.Z < 0f)
2538 agent_control_v3.Z = 0;
2539 // else if(AgentControlStopActive %% Velocity.Z <0.01f)
2542 // m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0}
for {1}
", MovementFlag, Name);
2544 // If the agent update does move the avatar, then calculate the force ready for the velocity update,
2545 // which occurs later in the main scene loop
2546 // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they
2547 // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update
2548 // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the
2549 // avatar location in place).
2550 if (update_movementflag
2551 || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0)))
2554 if (AgentControlStopActive)
2556 // if (MovementFlag == 0 && Animator.Falling)
2557 if (MovementFlag == 0 && Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling)
2559 AddNewMovement(agent_control_v3, AgentControlStopSlowVel, true);
2562 AddNewMovement(agent_control_v3, AgentControlStopSlowVel);
2566 AddNewMovement(agent_control_v3);
2571 if (update_movementflag && ParentID == 0)
2573 // m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations
for {0}
", Name);
2574 Animator.UpdateMovementAnimations();
2577 SendControlsToScripts(flagsForScripts);
2580 // We need to send this back to the client in order to see the edit beams
2581 if ((State & (uint)AgentState.Editing) != 0)
2582 SendAgentTerseUpdate(this);
2584 // m_scene.EventManager.TriggerOnClientMovement(this);
2591 private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
2593 //m_log.DebugFormat(
2594 // "[SCENE PRESENCE]: In {0} received
agent camera update from {1}, flags {2}
",
2595 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
2599 // // m_log.Debug("DEBUG: HandleAgentUpdate: child
agent");
2603 ++m_movementUpdateCount;
2604 if (m_movementUpdateCount < 1)
2605 m_movementUpdateCount = 1;
2607 // AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
2609 // Camera location in world. We'll need to raytrace
2610 // from this location from time to time.
2611 CameraPosition = agentData.CameraCenter;
2612 // Use these three vectors to figure out what the agent is looking at
2613 // Convert it to a Matrix and/or Quaternion
2614 CameraAtAxis = agentData.CameraAtAxis;
2615 CameraLeftAxis = agentData.CameraLeftAxis;
2616 CameraUpAxis = agentData.CameraUpAxis;
2618 // The Agent's Draw distance setting
2619 // When we get to the point of re-computing neighbors everytime this
2620 // changes, then start using the agent's drawdistance rather than the
2621 // region's draw distance.
2623 DrawDistance = agentData.Far;
2625 // Check if Client has camera in 'follow cam' or 'build' mode.
2626 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
2628 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
2629 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
2632 //m_log.DebugFormat("[FollowCam]: {0}
", m_followCamAuto);
2633 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
2634 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
2636 if (m_followCamAuto)
2638 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
2639 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
2643 TriggerScenePresenceUpdated();
2654 public bool HandleMoveToTargetUpdate(float tolerance, ref Vector3 agent_control_v3)
2656 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}
", Name);
2658 bool updated = false;
2660 Vector3 LocalVectorToTarget3D = MoveToPositionTarget - AbsolutePosition;
2662 // m_log.DebugFormat(
2663 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}
",
2664 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
2666 float distanceToTarget;
2667 if(Flying && !LandAtTarget)
2669 distanceToTarget = LocalVectorToTarget3D.Length();
2673 Vector3 hdist = LocalVectorToTarget3D;
2675 distanceToTarget = hdist.Length();
2678 // m_log.DebugFormat(
2679 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}
",
2680 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
2682 // Check the error term of the current position in relation to the target position
2683 if (distanceToTarget <= tolerance)
2685 // We are close enough to the target
2686 Velocity = Vector3.Zero;
2687 AbsolutePosition = MoveToPositionTarget;
2693 // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
2694 // the target if flying.
2695 // We really need to be more subtle (slow the avatar as it approaches the target) or at
2696 // least be able to set collision status once, rather than 5 times to give it enough
2697 // weighting so that that PhysicsActor thinks it really is colliding.
2698 for (int i = 0; i < 5; i++)
2701 ResetMoveToTarget();
2708 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
2709 // This movement vector gets added to the velocity through AddNewMovement().
2710 // Theoretically we might need a more complex PID approach here if other
2711 // unknown forces are acting on the avatar and we need to adaptively respond
2712 // to such forces, but the following simple approach seems to works fine.
2714 LocalVectorToTarget3D = LocalVectorToTarget3D * Quaternion.Inverse(Rotation); // change to avatar coords
2716 LocalVectorToTarget3D.Normalize();
2718 // update avatar movement flags. the avatar coordinate system is as follows:
2727 // (left) +Y <--------o--------> -Y
2737 // based on the above avatar coordinate system, classify the movement into
2738 // one of left/right/back/forward.
2740 const uint noMovFlagsMask = (uint)(~(Dir_ControlFlags.DIR_CONTROL_FLAG_BACK |
2741 Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD | Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT |
2742 Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT | Dir_ControlFlags.DIR_CONTROL_FLAG_UP |
2743 Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN));
2745 MovementFlag &= noMovFlagsMask;
2746 AgentControlFlags &= noMovFlagsMask;
2748 if (LocalVectorToTarget3D.X < 0) //MoveBack
2750 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
2751 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
2754 else if (LocalVectorToTarget3D.X > 0) //Move Forward
2756 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
2757 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
2761 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
2763 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
2764 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
2767 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
2769 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
2770 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
2774 if (LocalVectorToTarget3D.Z > 0) //Up
2776 // Don't set these flags for up or down - doing so will make the avatar crouch or
2777 // keep trying to jump even if walking along level ground
2778 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
2780 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
2783 else if (LocalVectorToTarget3D.Z < 0) //Down
2785 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
2786 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
2790 // m_log.DebugFormat(
2791 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move
vector {1}
for {2}
",
2792 // LocalVectorToTarget3D, agent_control_v3, Name);
2794 agent_control_v3 += LocalVectorToTarget3D;
2798 //Avoid system crash, can be slower but...
2799 m_log.DebugFormat("Crash! {0}
", e.ToString());
2804 // AddNewMovement(agent_control_v3);
2819 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
2824 // m_log.DebugFormat(
2825 // "[SCENE PRESENCE]:
Avatar {0} received request to move to position {1} in {2}
",
2826 // Name, pos, m_scene.RegionInfo.RegionName);
2828 // Allow move to another sub-region within a megaregion
2830 IRegionCombinerModule regionCombinerModule = m_scene.RequestModuleInterface<IRegionCombinerModule>();
2831 if (regionCombinerModule != null)
2832 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
2834 regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
2836 if (pos.X < 0 || pos.X >= regionSize.X
2837 || pos.Y < 0 || pos.Y >= regionSize.Y
2841 float terrainHeight;
2842 Scene targetScene = m_scene;
2843 // Get terrain height for sub-region in a megaregion if necessary
2844 if (regionCombinerModule != null)
2846 int X = (int)((m_scene.RegionInfo.WorldLocX) + pos.X);
2847 int Y = (int)((m_scene.RegionInfo.WorldLocY) + pos.Y);
2848 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y);
2849 // If X and Y is NaN, target_region will be null
2850 if (target_region == null)
2852 UUID target_regionID = target_region.RegionID;
2853 SceneManager.Instance.TryGetScene(target_region.RegionID, out targetScene);
2854 terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % regionSize.X), (int)(pos.Y % regionSize.Y)];
2857 terrainHeight = m_scene.GetGroundHeight(pos.X, pos.Y);
2859 // dont try to land underground
2860 terrainHeight += Appearance.AvatarHeight * 0.5f + 0.2f;
2862 if(terrainHeight > pos.Z)
2863 pos.Z = terrainHeight;
2865 // m_log.DebugFormat(
2866 // "[SCENE PRESENCE]:
Avatar {0} set move to target {1} (terrain height {2}) in {3}
",
2867 // Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
2871 else if (pos.Z > terrainHeight || Flying)
2874 LandAtTarget = landAtTarget;
2875 MovingToTarget = true;
2876 MoveToPositionTarget = pos;
2878 // Rotate presence around the z-axis to point in same direction as movement.
2879 // Ignore z component of vector
2880 Vector3 localVectorToTarget3D = pos - AbsolutePosition;
2881 Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f);
2883 // m_log.DebugFormat("[SCENE PRESENCE]: Local
vector to target is {0}
", localVectorToTarget2D);
2885 // Calculate the yaw.
2886 Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X)));
2888 // m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}
", angle);
2890 Rotation = Quaternion.CreateFromEulers(angle);
2891 // m_log.DebugFormat("[SCENE PRESENCE]:
Body rot
for {0} set to {1}
", Name, Rotation);
2893 Vector3 control = Vector3.Zero;
2894 if(HandleMoveToTargetUpdate(1f, ref control))
2895 AddNewMovement(control);
2901 public void ResetMoveToTarget()
2903 // m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target
for {0}
", Name);
2905 MovingToTarget = false;
2906 // MoveToPositionTarget = Vector3.Zero;
2907 m_forceToApply = null; // cancel possible last action
2909 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2910 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
2911 // However, the line is here rather than in the NPC module since it also appears necessary to stop a
2912 // viewer that uses "go here
" from juddering on all subsequent avatar movements.
2913 AgentControlFlags = (uint)AgentManager.ControlFlags.NONE;
2920 public void StandUp()
2922 // m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}
", Name);
2924 bool satOnObject = IsSatOnObject;
2925 SceneObjectPart part = ParentPart;
2930 PrevSitOffset = m_pos; // Save sit offset
2931 UnRegisterSeatControls(part.ParentGroup.UUID);
2933 TaskInventoryDictionary taskIDict = part.TaskInventory;
2934 if (taskIDict != null)
2938 foreach (UUID taskID in taskIDict.Keys)
2940 UnRegisterControlEventsToScript(LocalId, taskID);
2941 taskIDict[taskID].PermsMask &= ~(
2942 2048 | //PERMISSION_CONTROL_CAMERA
2943 4); // PERMISSION_TAKE_CONTROLS
2948 // part.ParentGroup.DeleteAvatar(UUID);
2950 Quaternion standRotation = part.ParentGroup.RootPart.RotationOffset;
2951 Vector3 sitPartWorldPosition = part.ParentGroup.AbsolutePosition + m_pos * standRotation;
2952 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2957 if (part.SitTargetAvatar == UUID)
2958 standRotation = standRotation * part.SitTargetOrientation;
2960 standRotation = standRotation * m_bodyRot;
2962 m_bodyRot = standRotation;
2964 Quaternion standRotationZ = new Quaternion(0,0,standRotation.Z,standRotation.W);
2966 float t = standRotationZ.W * standRotationZ.W + standRotationZ.Z * standRotationZ.Z;
2969 t = 1.0f / (float)Math.Sqrt(t);
2970 standRotationZ.W *= t;
2971 standRotationZ.Z *= t;
2975 standRotationZ.W = 1.0f;
2976 standRotationZ.Z = 0f;
2979 Vector3 adjustmentForSitPose = new Vector3(0.75f, 0, m_sitAvatarHeight + .3f) * standRotationZ;
2981 Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose;
2985 // We need to wait until we have calculated proper stand positions before sitting up the physical
2986 // avatar to avoid race conditions.
2987 if (PhysicsActor == null)
2988 AddToPhysicalScene(false);
2992 m_requestedSitTargetID = 0;
2993 part.RemoveSittingAvatar(this);
2994 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2996 SendAvatarDataToAllAgents();
2999 // reset to default sitAnimation
3000 sitAnimation = "SIT
";
3002 // Animator.TrySetMovementAnimation("STAND
");
3003 Animator.SetMovementAnimations("STAND
");
3005 TriggerScenePresenceUpdated();
3008 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
3010 SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID);
3011 if (targetPart == null)
3014 // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used.
3015 // 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.
3017 // Get our own copy of the part array, and sort into the order we want to test
3018 SceneObjectPart[] partArray = targetPart.ParentGroup.Parts;
3019 Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2)
3021 // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1)
3022 int linkNum1 = p1==targetPart ? -1 : p1.LinkNum;
3023 int linkNum2 = p2==targetPart ? -1 : p2.LinkNum;
3024 return linkNum1 - linkNum2;
3028 //look for prims with explicit sit targets that are available
3029 foreach (SceneObjectPart part in partArray)
3031 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
3033 //switch the target to this prim
3038 // no explicit sit target found - use original target
3042 private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation)
3044 Vector3 cameraEyeOffset = Vector3.Zero;
3045 Vector3 cameraAtOffset = Vector3.Zero;
3046 bool forceMouselook = false;
3048 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
3053 if (PhysicsActor != null)
3054 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
3056 bool canSit = false;
3058 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
3060 offset = part.SitTargetPosition;
3061 sitOrientation = part.SitTargetOrientation;
3067 if (PhysicsSit(part,offset)) // physics engine
3070 Vector3 pos = part.AbsolutePosition + offset;
3072 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
3074 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
3082 if (PhysicsActor != null)
3084 // We can remove the physicsActor until they stand up.
3085 RemoveFromPhysicalScene();
3089 ResetMoveToTarget();
3091 Velocity = Vector3.Zero;
3093 part.AddSittingAvatar(this);
3095 cameraAtOffset = part.GetCameraAtOffset();
3096 cameraEyeOffset = part.GetCameraEyeOffset();
3098 forceMouselook = part.GetForceMouselook();
3102 sitOrientation = part.RotationOffset * sitOrientation;
3103 offset = offset * part.RotationOffset;
3104 offset += part.OffsetPosition;
3106 if (CameraAtAxis == Vector3.Zero && cameraEyeOffset == Vector3.Zero)
3108 CameraAtAxis = part.ParentGroup.RootPart.GetCameraAtOffset();
3109 cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
3113 cameraAtOffset = cameraAtOffset * part.RotationOffset;
3114 cameraAtOffset += part.OffsetPosition;
3115 cameraEyeOffset = cameraEyeOffset * part.RotationOffset;
3116 cameraEyeOffset += part.OffsetPosition;
3120 ControllingClient.SendSitResponse(
3121 part.ParentGroup.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
3123 m_requestedSitTargetUUID = part.UUID;
3125 HandleAgentSit(ControllingClient, UUID);
3127 // Moved here to avoid a race with default sit anim
3128 // The script event needs to be raised after the default sit anim is set.
3129 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
3133 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
3140 if (ParentPart.UUID == targetID)
3141 return; // already sitting here, ignore
3146 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
3150 m_requestedSitTargetID = part.LocalId;
3151 m_requestedSitTargetUUID = part.UUID;
3155 m_log.Warn("Sit requested on unknown
object:
" + targetID.ToString());
3158 SendSitResponse(targetID, offset, Quaternion.Identity);
3161 // returns false if does not suport so older sit can be tried
3162 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
3164 if (part == null || part.ParentGroup.IsAttachment)
3167 if ( m_scene.PhysicsScene == null)
3170 if (part.PhysActor == null)
3172 // none physcis shape
3173 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
3174 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on,
try another spot.
");
3176 { // non physical phantom TODO
3177 // ControllingClient.SendAlertMessage(" There is no suitable surface to sit on,
try another spot.
");
3183 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
3192 private bool CanEnterLandPosition(Vector3 testPos)
3194 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
3196 if (land == null || land.LandData.Name == "NO_LAND
")
3199 return land.CanBeOnThisLand(UUID,testPos.Z);
3205 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
3212 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on,
try another spot.
");
3216 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
3220 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
3221 if(!CanEnterLandPosition(targetPos))
3223 ControllingClient.SendAlertMessage(" Sit position on restricted
land,
try another spot
");
3227 RemoveFromPhysicalScene();
3230 ResetMoveToTarget();
3232 Velocity = Vector3.Zero;
3233 m_AngularVelocity = Vector3.Zero;
3235 Vector3 cameraAtOffset = part.GetCameraAtOffset();
3236 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
3237 bool forceMouselook = part.GetForceMouselook();
3239 m_bodyRot = Orientation;
3243 Orientation = part.RotationOffset * Orientation;
3244 offset = offset * part.RotationOffset;
3245 offset += part.OffsetPosition;
3247 if (CameraAtAxis == Vector3.Zero && cameraEyeOffset == Vector3.Zero)
3249 CameraAtAxis = part.ParentGroup.RootPart.GetCameraAtOffset();
3250 cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
3254 cameraAtOffset = cameraAtOffset * part.RotationOffset;
3255 cameraAtOffset += part.OffsetPosition;
3256 cameraEyeOffset = cameraEyeOffset * part.RotationOffset;
3257 cameraEyeOffset += part.OffsetPosition;
3263 ControllingClient.SendSitResponse(
3264 part.ParentGroup.UUID, offset, Orientation, true, cameraAtOffset, cameraEyeOffset, forceMouselook);
3267 m_requestedSitTargetID = 0;
3268 part.AddSittingAvatar(this);
3271 ParentID = part.LocalId;
3273 SendAvatarDataToAllAgents();
3276 sitAnimation = "SIT_GROUND
";
3278 sitAnimation = "SIT
";
3280 Animator.SetMovementAnimations("SIT
");
3281 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
3284 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
3289 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
3293 if (part.ParentGroup.IsAttachment)
3296 "[SCENE PRESENCE]:
Avatar {0} tried to sit on part {1} from
object {2} in {3} but
this is an attachment
for avatar
id {4}
",
3297 Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar);
3302 if (part.SitTargetAvatar == UUID)
3304 Vector3 sitTargetPos = part.SitTargetPosition;
3305 Quaternion sitTargetOrient = part.SitTargetOrientation;
3307 // m_log.DebugFormat(
3308 // "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}
",
3309 // Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId);
3313 Quaternion r = sitTargetOrient;
3315 if(LegacySitOffsets)
3319 m1 = r.X * r.X + r.Y * r.Y;
3320 m2 = r.Z * r.Z + r.W * r.W;
3322 // Rotate the vector <0, 0, 1>
3323 x = 2 * (r.X * r.Z + r.Y * r.W);
3324 y = 2 * (-r.X * r.W + r.Y * r.Z);
3327 // Set m to be the square of the norm of r.
3330 // This constant is emperically determined to be what is used in SL.
3331 // See also http://opensimulator.org/mantis/view.php?id=7096
3332 double offset = 0.05;
3334 // Normally m will be ~ 1, but if someone passed a handcrafted quaternion
3335 // to llSitTarget with values so small that squaring them is rounded off
3336 // to zero, then m could be zero. The result of this floating point
3337 // round off error (causing us to skip this impossible normalization)
3344 Vector3 up = new Vector3((float)x, (float)y, (float)z);
3345 sitOffset = up * (float)offset;
3349 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
3351 if (Math.Abs(1.0 - m) > 0.000001)
3355 m = 1.0 / Math.Sqrt(m);
3371 x = 2 * (r.X * r.Z + r.Y * r.W);
3372 y = 2 * (-r.X * r.W + r.Y * r.Z);
3373 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
3374 Vector3 up = new Vector3((float)x, (float)y, (float)z);
3375 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
3378 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
3383 newRot = sitTargetOrient;
3387 newPos = newPos * part.RotationOffset;
3388 newRot = part.RotationOffset * sitTargetOrient;
3391 newPos += part.OffsetPosition;
3396 // ParentPosition = part.AbsolutePosition;
3400 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
3402 m_pos -= part.GroupPosition;
3404 // ParentPosition = part.AbsolutePosition;
3406 // m_log.DebugFormat(
3407 // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target
",
3408 // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
3411 part.AddSittingAvatar(this);
3413 ParentID = m_requestedSitTargetID;
3414 m_AngularVelocity = Vector3.Zero;
3415 Velocity = Vector3.Zero;
3416 RemoveFromPhysicalScene();
3418 m_requestedSitTargetID = 0;
3420 SendAvatarDataToAllAgents();
3422 sitAnimation = "SIT
";
3423 if (!String.IsNullOrEmpty(part.SitAnimation))
3425 sitAnimation = part.SitAnimation;
3427 // Animator.TrySetMovementAnimation(sitAnimation);
3428 Animator.SetMovementAnimations("SIT
");
3429 TriggerScenePresenceUpdated();
3433 public void HandleAgentSitOnGround()
3438 // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick..
3439 m_AngularVelocity = Vector3.Zero;
3440 sitAnimation = "SIT_GROUND_CONSTRAINED
";
3441 // Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED
");
3442 // TriggerScenePresenceUpdated();
3444 RemoveFromPhysicalScene();
3446 Animator.SetMovementAnimations("SITGROUND
");
3447 TriggerScenePresenceUpdated();
3454 public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun)
3456 SetAlwaysRun = pSetAlwaysRun;
3459 public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
3461 Animator.AddAnimation(animID, UUID.Zero);
3462 TriggerScenePresenceUpdated();
3465 public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
3467 Animator.RemoveAnimation(animID, false);
3468 TriggerScenePresenceUpdated();
3471 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
3473 Animator.avnChangeAnim(animID, addRemove, sendPack);
3484 public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1, bool breaking = false)
3486 // m_log.DebugFormat(
3487 // "[SCENE PRESENCE]: Adding
new movement {0} with
rotation {1}, thisAddSpeedModifier {2}
for {3}
",
3488 // vec, Rotation, thisAddSpeedModifier, Name);
3490 // rotate from avatar coord space to world
3491 // for now all controls assume this is only a rotation around Z
3492 // if not all checks below need to be done before this rotation
3493 Vector3 direc = vec * Rotation;
3496 // mouse look situation ?
3497 if ((vec.Z == 0f) && !Flying)
3498 direc.Z = 0f; // Prevent camera WASD up.
3501 direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier;
3503 // m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0}
for {1}
", direc, Name);
3505 if (Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling
3506 && (PhysicsActor == null || !PhysicsActor.PIDHoverActive))
3509 direc.Z = -9999f; //hack to tell physics to stop on Z
3511 direc = Vector3.Zero;
3515 if (IsColliding && direc.Z < 0)
3516 // landing situation, prevent avatar moving or it may fail to land
3517 // animator will handle this condition and do the land
3518 direc = Vector3.Zero;
3522 else if (IsColliding)
3524 if (direc.Z > 2.0f) // reinforce jumps
3528 else if (direc.Z < 0) // on a surface moving down (pg down) only changes animation
3532 // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0}
for {1}
", direc, Name);
3534 m_forceToApply = direc;
3535 Animator.UpdateMovementAnimations();
3540 #region Overridden Methods
3542 const float ROTATION_TOLERANCE = 0.01f;
3543 const float VELOCITY_TOLERANCE = 0.1f;
3544 const float LOWVELOCITYSQ = 0.1f;
3545 const float POSITION_LARGETOLERANCE = 5f;
3546 const float POSITION_SMALLTOLERANCE = 0.05f;
3548 public override void Update()
3550 if(IsChildAgent || IsDeleted)
3553 CheckForBorderCrossing();
3555 if (IsInTransit || IsLoggingIn)
3560 Vector3 control = Vector3.Zero;
3561 if(HandleMoveToTargetUpdate(1f, ref control))
3562 AddNewMovement(control);
3565 if (Appearance.AvatarSize != m_lastSize)
3566 SendAvatarDataToAllAgents();
3568 // Send terse position update if not sitting and position, velocity, or rotation
3569 // has changed significantly from last sent update
3570 if (!IsSatOnObject && (
3571 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3572 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
3573 || !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE)
3574 // if velocity is zero and it wasn't zero last time, send the update
3575 || (Velocity == Vector3.Zero && m_lastVelocity != Vector3.Zero)
3576 // if position has moved just a little and velocity is very low, send the update
3577 || (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ )
3583 // this does need to be more complex later
3584 Vector3 vel = Velocity;
3585 Vector3 dpos = m_pos - m_lastPosition;
3586 if( Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3587 Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3588 Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE ||
3590 Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE ||
3591 Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE ||
3592 Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE ||
3594 Math.Abs(dpos.X) > POSITION_LARGETOLERANCE ||
3595 Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE ||
3596 Math.Abs(dpos.Z) > POSITION_LARGETOLERANCE ||
3598 ( (Math.Abs(dpos.X) > POSITION_SMALLTOLERANCE ||
3599 Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE ||
3600 Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE)
3601 && vel.LengthSquared() < LOWVELOCITYSQ
3605 SendTerseUpdateToAllClients();
3608 CheckForSignificantMovement();
3613 #region Update Client(s)
3615 public void SendUpdateToAgent(ScenePresence p)
3617 IClientAPI remoteClient = p.ControllingClient;
3619 if (remoteClient.IsActive)
3621 //m_log.DebugFormat("[SCENE PRESENCE]:
" + Name + " sending TerseUpdate to
" + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}
", m_pos, Rotation, m_velocity);
3622 remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
3623 m_scene.StatsReporter.AddAgentUpdates(1);
3627 public void SendFullUpdateToClient(IClientAPI remoteClient)
3629 if (remoteClient.IsActive)
3631 //m_log.DebugFormat("[SCENE PRESENCE]:
" + Name + " sending TerseUpdate to
" + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}
", m_pos, Rotation, m_velocity);
3632 remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
3633 m_scene.StatsReporter.AddAgentUpdates(1);
3637 // this is diferente from SendTerseUpdateToClient
3638 // this sends bypassing entities updates
3639 public void SendAgentTerseUpdate(ISceneEntity p)
3641 ControllingClient.SendAgentTerseUpdate(p);
3649 public void SendTerseUpdateToClient(IClientAPI remoteClient)
3651 // If the client is inactive, it's getting its updates from another
3653 if (remoteClient.IsActive)
3655 //m_log.DebugFormat("[SCENE PRESENCE]:
" + Name + " sending TerseUpdate to
" + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}
", m_pos, Rotation, m_velocity);
3656 remoteClient.SendEntityUpdate(
3658 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
3659 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
3661 m_scene.StatsReporter.AddAgentUpdates(1);
3665 public void SendTerseUpdateToAgent(ScenePresence p)
3667 IClientAPI remoteClient = p.ControllingClient;
3669 if (!remoteClient.IsActive)
3672 if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodLevel < 200)
3675 //m_log.DebugFormat("[SCENE PRESENCE]:
" + Name + " sending TerseUpdate to
" + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}
", m_pos, Rotation, m_velocity);
3676 remoteClient.SendEntityUpdate(
3678 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
3679 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
3681 m_scene.StatsReporter.AddAgentUpdates(1);
3684 public void SendTerseUpdateToAgentNF(ScenePresence p)
3686 IClientAPI remoteClient = p.ControllingClient;
3687 if (remoteClient.IsActive)
3689 //m_log.DebugFormat("[SCENE PRESENCE]:
" + Name + " sending TerseUpdate to
" + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}
", m_pos, Rotation, m_velocity);
3690 remoteClient.SendEntityUpdate(this,
3691 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
3692 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
3693 m_scene.StatsReporter.AddAgentUpdates(1);
3700 public void SendTerseUpdateToAllClients()
3702 m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
3703 // Update the "last
" values
3704 m_lastPosition = m_pos;
3705 m_lastRotation = m_bodyRot;
3706 m_lastVelocity = Velocity;
3707 TriggerScenePresenceUpdated();
3710 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
3712 SendCoarseLocationsMethod d = m_sendCoarseLocationsMethod;
3715 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
3719 public void SetSendCoarseLocationMethod(SendCoarseLocationsMethod d)
3722 m_sendCoarseLocationsMethod = d;
3725 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
3727 ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
3730 public void SendInitialDataToMe()
3732 // Send all scene object to the new client
3733 Util.FireAndForget(delegate
3735 // we created a new ScenePresence (a new child agent) in a fresh region.
3736 // Request info about all the (root) agents in this region
3737 // Note: This won't send data *to* other clients in that region (children don't send)
3738 if (m_teleportFlags <= 0)
3740 Scene.SendLayerData(ControllingClient);
3742 ILandChannel landch = m_scene.LandChannel;
3745 landch.sendClientInitialLandInfo(ControllingClient);
3749 SendOtherAgentsAvatarFullToMe();
3750 EntityBase[] entities = Scene.Entities.GetEntities();
3751 foreach (EntityBase e in entities)
3753 if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
3754 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
3763 public void SendOtherAgentsAvatarFullToMe()
3766 m_scene.ForEachRootScenePresence(delegate(ScenePresence p)
3768 // only send information about other root agents
3772 // get the avatar, then a kill if can't see it
3773 p.SendInitialAvatarDataToAgent(this);
3775 if (p.ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && GodLevel < 200)
3778 p.SendAppearanceToAgentNF(this);
3779 p.SendAnimPackToAgentNF(this);
3780 p.SendAttachmentsToAgentNF(this);
3784 m_scene.StatsReporter.AddAgentUpdates(count);
3791 public void SendAvatarDataToAllAgents()
3793 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})
", Name, UUID);
3794 // only send update from root agents to other clients; children are only "listening posts
"
3798 "[SCENE PRESENCE]: Attempt to send avatar data from a child agent
for {0} in {1}
",
3799 Name, Scene.RegionInfo.RegionName);
3803 m_lastSize = Appearance.AvatarSize;
3806 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3808 SendAvatarDataToAgent(scenePresence);
3812 m_scene.StatsReporter.AddAgentUpdates(count);
3814 // sends avatar object to all clients so they cross it into region
3815 // then sends kills to hide
3816 public void SendInitialAvatarDataToAllAgents(List<ScenePresence> presences)
3818 m_lastSize = Appearance.AvatarSize;
3820 foreach (ScenePresence p in presences)
3822 p.ControllingClient.SendAvatarDataImmediate(this);
3823 if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
3824 // either just kill the object
3825 // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
3826 // or also attachments viewer may still know about
3830 m_scene.StatsReporter.AddAgentUpdates(count);
3833 public void SendInitialAvatarDataToAgent(ScenePresence p)
3835 p.ControllingClient.SendAvatarDataImmediate(this);
3836 if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
3837 // either just kill the object
3838 // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
3839 // or also attachments viewer may still know about
3847 public void SendAvatarDataToAgent(ScenePresence avatar)
3849 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})
", Name, UUID, avatar.Name, avatar.UUID);
3850 if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200)
3852 avatar.ControllingClient.SendAvatarDataImmediate(this);
3855 public void SendAvatarDataToAgentNF(ScenePresence avatar)
3857 avatar.ControllingClient.SendAvatarDataImmediate(this);
3864 public void SendAppearanceToAllOtherAgents()
3866 // m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}
", Name, UUID);
3868 // only send update from root agents to other clients; children are only "listening posts
"
3872 "[SCENE PRESENCE]: Attempt to send avatar data from a child
agent for {0} in {1}
",
3873 Name, Scene.RegionInfo.RegionName);
3879 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3881 // only send information to other root agents
3882 if (scenePresence.UUID == UUID)
3885 SendAppearanceToAgent(scenePresence);
3888 m_scene.StatsReporter.AddAgentUpdates(count);
3891 public void SendAppearanceToAgent(ScenePresence avatar)
3893 // m_log.DebugFormat(
3894 // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}
", Name, m_uuid, avatar.Name, avatar.UUID);
3895 if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200)
3897 SendAppearanceToAgentNF(avatar);
3900 public void SendAppearanceToAgentNF(ScenePresence avatar)
3902 avatar.ControllingClient.SendAppearance(
3903 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3906 public void SendAnimPackToAgent(ScenePresence p)
3908 if (IsChildAgent || Animator == null)
3911 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
3914 Animator.SendAnimPackToClient(p.ControllingClient);
3917 public void SendAnimPackToAgent(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs)
3922 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
3925 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
3928 public void SendAnimPackToAgentNF(ScenePresence p)
3930 if (IsChildAgent || Animator == null)
3932 Animator.SendAnimPackToClient(p.ControllingClient);
3935 public void SendAnimPackToAgentNF(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs)
3937 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
3940 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
3945 m_scene.ForEachScenePresence(delegate(ScenePresence p)
3947 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
3949 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
3955 #region Significant Movement Method
3957 private void checkRePrioritization()
3959 if(IsDeleted || !ControllingClient.IsActive)
3962 if(m_reprioritizationBusy)
3965 int tdiff = Util.EnvironmentTickCountSubtract(m_reprioritizationLastTime);
3966 if(tdiff < Scene.ReprioritizationInterval)
3968 // priority uses avatar position
3969 Vector3 pos = AbsolutePosition;
3970 Vector3 diff = pos - m_reprioritizationLastPosition;
3973 limit = (float)Scene.ChildReprioritizationDistance;
3975 limit = (float)Scene.RootReprioritizationDistance;
3978 if (diff.LengthSquared() < limit)
3981 m_reprioritizationBusy = true;
3982 m_reprioritizationLastPosition = pos;
3987 ControllingClient.ReprioritizeUpdates();
3988 m_reprioritizationLastTime = Util.EnvironmentTickCount();
3989 m_reprioritizationBusy = false;
3990 }, null, "ScenePresence.Reprioritization
");
3995 protected void CheckForSignificantMovement()
3997 Vector3 pos = AbsolutePosition;
3999 Vector3 diff = pos - posLastMove;
4000 if (diff.LengthSquared() > MOVEMENT)
4003 m_scene.EventManager.TriggerOnClientMovement(this);
4006 diff = pos - posLastSignificantMove;
4007 if (diff.LengthSquared() > SIGNIFICANT_MOVEMENT)
4009 posLastSignificantMove = pos;
4010 m_scene.EventManager.TriggerSignificantClientMovement(this);
4013 // updates priority recalc
4014 checkRePrioritization();
4016 if(childUpdatesBusy)
4019 //possible KnownRegionHandles always contains current region and this check is not needed
4021 if(KnownRegionHandles.Contains(RegionHandle))
4024 if(KnownRegionHandles.Count > minhandles)
4026 int tdiff = Util.EnvironmentTickCountSubtract(lastChildUpdatesTime);
4027 if(tdiff > CHILDUPDATES_TIME)
4029 diff = pos - m_lastChildAgentUpdatePosition;
4030 if (diff.LengthSquared() > CHILDUPDATES_MOVEMENT)
4032 childUpdatesBusy = true;
4033 m_lastChildAgentUpdatePosition = pos;
4034 // m_lastChildAgentUpdateCamPosition = CameraPosition;
4036 AgentPosition agentpos = new AgentPosition();
4037 agentpos.AgentID = new UUID(UUID.Guid);
4038 agentpos.SessionID = ControllingClient.SessionId;
4039 agentpos.Size = Appearance.AvatarSize;
4040 agentpos.Center = CameraPosition;
4041 agentpos.Far = DrawDistance;
4042 agentpos.Position = AbsolutePosition;
4043 agentpos.Velocity = Velocity;
4044 agentpos.RegionHandle = RegionHandle;
4045 agentpos.Throttles = ControllingClient.GetThrottlesPacked(1);
4047 // Let's get this out of the update loop
4051 m_scene.SendOutChildAgentUpdates(agentpos, this);
4052 lastChildUpdatesTime = Util.EnvironmentTickCount();
4053 childUpdatesBusy = false;
4054 }, null, "ScenePresence.SendOutChildAgentUpdates
");
4062 #region Border Crossing Methods
4070 protected void CheckForBorderCrossing()
4072 // Check that we we are not a child
4073 if (IsChildAgent || IsInTransit)
4076 // If we don't have a PhysActor, we can't cross anyway
4077 // Also don't do this while sat, sitting avatars cross with the
4078 // object they sit on. ParentUUID denoted a pending sit, don't
4079 // interfere with it.
4080 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
4083 Vector3 pos2 = AbsolutePosition;
4084 Vector3 vel = Velocity;
4086 float timeStep = 0.1f;
4087 pos2.X += vel.X * timeStep;
4088 pos2.Y += vel.Y * timeStep;
4089 pos2.Z += vel.Z * timeStep;
4091 // m_log.DebugFormat(
4092 // "[SCENE PRESENCE]: Testing border check
for projected position {0} of {1} in {2}
",
4093 // pos2, Name, Scene.Name);
4095 if (Scene.PositionIsInCurrentRegion(pos2))
4098 if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero)
4100 // we don't have entity transfer module
4101 Vector3 pos = AbsolutePosition;
4104 pos.X += Velocity.X * 2;
4105 else if (px > m_scene.RegionInfo.RegionSizeX)
4106 pos.X -= Velocity.X * 2;
4110 pos.Y += Velocity.Y * 2;
4111 else if (py > m_scene.RegionInfo.RegionSizeY)
4112 pos.Y -= Velocity.Y * 2;
4114 Velocity = Vector3.Zero;
4115 AbsolutePosition = pos;
4119 public void CrossToNewRegionFail()
4121 if (m_requestedSitTargetUUID == UUID.Zero)
4123 bool isFlying = Flying;
4124 RemoveFromPhysicalScene();
4126 Vector3 pos = AbsolutePosition;
4129 pos.X += Velocity.X * 2;
4130 else if (px > m_scene.RegionInfo.RegionSizeX)
4131 pos.X -= Velocity.X * 2;
4135 pos.Y += Velocity.Y * 2;
4136 else if (py > m_scene.RegionInfo.RegionSizeY)
4137 pos.Y -= Velocity.Y * 2;
4139 Velocity = Vector3.Zero;
4140 AbsolutePosition = pos;
4142 AddToPhysicalScene(isFlying);
4152 protected bool CrossToNewRegion()
4154 bool result = false;
4155 // parcelRegionCross(false);
4158 result = m_scene.CrossAgentToNewRegion(this, Flying);
4162 // result = m_scene.CrossAgentToNewRegion(this, false);
4166 // parcelRegionCross(true);
4172 /* useless. Either use MakeChild or delete the presence
4175 // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}
", Name, Scene.RegionInfo.RegionName);
4177 // Put the child agent back at the center
4179 = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70);
4181 Animator.ResetAnimations();
4191 public void CloseChildAgents(bool logout, ulong newRegionHandle, int newRegionSizeX, int newRegionSizeY)
4193 uint newRegionX, newRegionY;
4194 List<ulong> byebyeRegions = new List<ulong>();
4195 List<ulong> knownRegions = KnownRegionHandles;
4197 "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}
",
4198 knownRegions.Count, Scene.RegionInfo.RegionName);
4199 //DumpKnownRegions();
4201 Util.RegionHandleToRegionLoc(newRegionHandle, out newRegionX, out newRegionY);
4204 spRegionSizeInfo regInfo;
4206 // this should not be here
4207 IEventQueue eventQueue = Scene.RequestModuleInterface<IEventQueue>();
4209 foreach (ulong handle in knownRegions)
4211 // Don't close the agent on this region yet
4212 if (handle != Scene.RegionInfo.RegionHandle)
4215 byebyeRegions.Add(handle);
4218 Util.RegionHandleToRegionLoc(handle, out x, out y);
4219 if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out regInfo))
4222 // m_log.Debug("---> x:
" + x + "; newx:
" + newRegionX + "; Abs:
" + (int)Math.Abs((int)(x - newRegionX)));
4223 // m_log.Debug("---> y:
" + y + "; newy:
" + newRegionY + "; Abs:
" + (int)Math.Abs((int)(y - newRegionY)));
4224 if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
4225 regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY))
4227 byebyeRegions.Add(handle);
4228 // this should not be here
4229 // if(eventQueue != null)
4235 if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
4236 (int)Constants.RegionSize, (int)Constants.RegionSize, newRegionSizeX, newRegionSizeY))
4238 byebyeRegions.Add(handle);
4239 // this should not be here
4240 // if(eventQueue != null)
4241 // eventQueue.DisableSimulator(handle,UUID);
4248 if (byebyeRegions.Count > 0)
4250 m_log.Debug("[SCENE PRESENCE]: Closing
" + byebyeRegions.Count + " child agents
");
4252 AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
4253 string auth = string.Empty;
4255 auth = acd.SessionID.ToString();
4256 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
4259 foreach (ulong handle in byebyeRegions)
4261 RemoveNeighbourRegion(handle);
4262 Scene.CapsModule.DropChildSeed(UUID, handle);
4272 public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus)
4274 int oldgodlevel = GodLevel;
4278 // For now, assign god level 200 to anyone
4279 // who is granted god powers, but has no god level set.
4281 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID);
4282 if (account != null)
4284 if (account.UserLevel > 0)
4285 GodLevel = account.UserLevel;
4295 ControllingClient.SendAdminResponse(token, (uint)GodLevel);
4297 if(oldgodlevel != GodLevel)
4298 parcelGodCheck(m_currentParcelUUID, GodLevel >= 200);
4301 #region Child Agent Updates
4303 public void UpdateChildAgent(AgentData cAgentData)
4309 CopyFrom(cAgentData);
4313 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
4315 private void RaiseUpdateThrottles()
4317 m_scene.EventManager.TriggerThrottleUpdate(this);
4324 public void UpdateChildAgent(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY)
4329 RegionHandle = cAgentData.RegionHandle;
4331 //m_log.Debug(" >>> ChildAgentPositionUpdate <<<
" + rRegionX + "-
" + rRegionY);
4332 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
4333 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
4335 Vector3 offset = new Vector3(shiftx, shifty, 0f);
4337 DrawDistance = cAgentData.Far;
4339 if (cAgentData.Position != marker) // UGH!!
4340 m_pos = cAgentData.Position + offset;
4342 CameraPosition = cAgentData.Center + offset;
4344 if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0)
4346 // some scaling factor
4348 if (x > m_scene.RegionInfo.RegionSizeX)
4349 x -= m_scene.RegionInfo.RegionSizeX;
4351 if (y > m_scene.RegionInfo.RegionSizeY)
4352 y -= m_scene.RegionInfo.RegionSizeY;
4356 const float distScale = 0.4f / Constants.RegionSize / Constants.RegionSize;
4357 float factor = 1.0f - distScale * x;
4361 ControllingClient.SetChildAgentThrottle(cAgentData.Throttles,factor);
4364 if(cAgentData.ChildrenCapSeeds != null && cAgentData.ChildrenCapSeeds.Count >0)
4366 if (Scene.CapsModule != null)
4368 Scene.CapsModule.SetChildrenSeed(UUID, cAgentData.ChildrenCapSeeds);
4371 KnownRegions = cAgentData.ChildrenCapSeeds;
4374 //cAgentData.AVHeight;
4375 //m_velocity = cAgentData.Velocity;
4376 checkRePrioritization();
4379 public void CopyTo(AgentData cAgent)
4381 cAgent.CallbackURI = m_callbackURI;
4383 cAgent.AgentID = UUID;
4384 cAgent.RegionID = Scene.RegionInfo.RegionID;
4385 cAgent.SessionID = ControllingClient.SessionId;
4387 cAgent.Position = AbsolutePosition;
4388 cAgent.Velocity = m_velocity;
4389 cAgent.Center = CameraPosition;
4390 cAgent.AtAxis = CameraAtAxis;
4391 cAgent.LeftAxis = CameraLeftAxis;
4392 cAgent.UpAxis = CameraUpAxis;
4394 cAgent.Far = DrawDistance;
4397 cAgent.Throttles = ControllingClient.GetThrottlesPacked(1);
4399 cAgent.HeadRotation = m_headrotation;
4400 cAgent.BodyRotation = Rotation;
4401 cAgent.ControlFlags = (uint)m_AgentControlFlags;
4403 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
4404 cAgent.GodLevel = (byte)GodLevel;
4406 cAgent.GodLevel = (byte) 0;
4408 cAgent.AlwaysRun = SetAlwaysRun;
4410 // make clear we want the all thing
4411 cAgent.Appearance = new AvatarAppearance(Appearance,true,true);
4413 cAgent.ParentPart = ParentUUID;
4414 cAgent.SitOffset = PrevSitOffset;
4416 lock (scriptedcontrols)
4418 ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
4421 foreach (ScriptControllers c in scriptedcontrols.Values)
4423 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
4425 cAgent.Controllers = controls;
4431 cAgent.Anims = Animator.Animations.ToArray();
4434 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
4435 cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation;
4437 cAgent.MovementAnimationOverRides = Overrides.CloneAOPairs();
4439 cAgent.MotionState = (byte)Animator.currentControlState;
4441 if (Scene.AttachmentsModule != null)
4442 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
4445 private void CopyFrom(AgentData cAgent)
4447 m_callbackURI = cAgent.CallbackURI;
4448 // m_log.DebugFormat(
4449 // "[SCENE PRESENCE]: Set callback
for {0} in {1} to {2} in CopyFrom()
",
4450 // Name, m_scene.RegionInfo.RegionName, m_callbackURI);
4452 m_pos = cAgent.Position;
4453 m_velocity = cAgent.Velocity;
4454 CameraPosition = cAgent.Center;
4455 CameraAtAxis = cAgent.AtAxis;
4456 CameraLeftAxis = cAgent.LeftAxis;
4457 CameraUpAxis = cAgent.UpAxis;
4458 ParentUUID = cAgent.ParentPart;
4459 PrevSitOffset = cAgent.SitOffset;
4461 // When we get to the point of re-computing neighbors everytime this
4462 // changes, then start using the agent's drawdistance rather than the
4463 // region's draw distance.
4464 DrawDistance = cAgent.Far;
4465 //DrawDistance = Scene.DefaultDrawDistance;
4467 if (cAgent.ChildrenCapSeeds != null && cAgent.ChildrenCapSeeds.Count > 0)
4469 if (Scene.CapsModule != null)
4471 Scene.CapsModule.SetChildrenSeed(UUID, cAgent.ChildrenCapSeeds);
4473 KnownRegions = cAgent.ChildrenCapSeeds;
4476 if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
4477 ControllingClient.SetChildAgentThrottle(cAgent.Throttles);
4479 m_headrotation = cAgent.HeadRotation;
4480 Rotation = cAgent.BodyRotation;
4481 m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags;
4483 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
4484 GodLevel = cAgent.GodLevel;
4485 SetAlwaysRun = cAgent.AlwaysRun;
4488 Appearance = new AvatarAppearance(cAgent.Appearance);
4490 bool isFlying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
4492 if (PhysicsActor != null)
4494 RemoveFromPhysicalScene();
4495 AddToPhysicalScene(isFlying);
4500 lock (scriptedcontrols)
4502 if (cAgent.Controllers != null)
4504 scriptedcontrols.Clear();
4506 foreach (ControllerData c in cAgent.Controllers)
4508 ScriptControllers sc = new ScriptControllers();
4509 sc.objectID = c.ObjectID;
4510 sc.itemID = c.ItemID;
4511 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
4512 sc.eventControls = (ScriptControlled)c.EventControls;
4514 scriptedcontrols[sc.itemID] = sc;
4521 Animator.ResetAnimations();
4523 Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides);
4525 // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object?
4526 if (cAgent.DefaultAnim != null)
4527 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
4528 if (cAgent.AnimState != null)
4529 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
4530 if (cAgent.Anims != null)
4531 Animator.Animations.FromArray(cAgent.Anims);
4532 if (cAgent.MotionState != 0)
4533 Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState;
4535 if (Scene.AttachmentsModule != null)
4536 Scene.AttachmentsModule.CopyAttachments(cAgent, this);
4538 lock (m_originRegionIDAccessLock)
4539 m_originRegionID = cAgent.RegionID;
4542 public bool CopyAgent(out IAgentData agent)
4544 agent = new CompleteAgentData();
4545 CopyTo((AgentData)agent);
4549 #endregion Child Agent Updates
4554 public void UpdateMovement()
4558 if (m_forceToApply.HasValue)
4560 Vector3 force = m_forceToApply.Value;
4564 m_forceToApply = null;
4565 TriggerScenePresenceUpdated();
4572 public void AddToPhysicalScene(bool isFlying)
4574 // m_log.DebugFormat(
4575 // "[SCENE PRESENCE]: Adding physics actor
for {0}, ifFlying = {1} in {2}
",
4576 // Name, isFlying, Scene.RegionInfo.RegionName);
4578 if (PhysicsActor != null)
4581 "[SCENE PRESENCE]: Adding physics actor
for {0} to {1} but
this scene presence already has a physics actor
",
4582 Name, Scene.RegionInfo.RegionName);
4585 if (Appearance.AvatarHeight == 0)
4586 // Appearance.SetHeight();
4587 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
4589 PhysicsScene scene = m_scene.PhysicsScene;
4590 Vector3 pVec = AbsolutePosition;
4592 PhysicsActor = scene.AddAvatar(
4593 LocalId, Firstname + ".
" + Lastname, pVec,
4594 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
4595 PhysicsActor.Orientation = m_bodyRot;
4596 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
4597 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
4598 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
4599 PhysicsActor.SubscribeEvents(100);
4600 PhysicsActor.LocalID = LocalId;
4603 private void OutOfBoundsCall(Vector3 pos)
4605 //bool flying = Flying;
4606 //RemoveFromPhysicalScene();
4608 //AddToPhysicalScene(flying);
4609 if (ControllingClient != null)
4610 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.
", true);
4625 public void PhysicsCollisionUpdate(EventArgs e)
4627 if (IsChildAgent || Animator == null)
4632 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
4633 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
4634 // as of this comment the interval is set in AddToPhysicalScene
4636 // if (m_updateCount > 0)
4638 if (Animator.UpdateMovementAnimations())
4639 TriggerScenePresenceUpdated();
4643 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
4644 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
4647 // // No collisions at all means we may be flying. Update always
4648 // // to make falling work
4649 // if (m_lastColCount != coldata.Count || coldata.Count == 0)
4651 // m_updateCount = UPDATE_COUNT;
4652 // m_lastColCount = coldata.Count;
4655 if (coldata.Count != 0)
4658 switch (Animator.CurrentMovementAnimation)
4667 ContactPoint lowest;
4668 lowest.SurfaceNormal = Vector3.Zero;
4669 lowest.Position = Vector3.Zero;
4670 lowest.Position.Z = float.MaxValue;
4672 foreach (ContactPoint contact in coldata.Values)
4675 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
4681 if (lowest.Position.Z != float.MaxValue)
4683 lowest.SurfaceNormal = -lowest.SurfaceNormal;
4684 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
4687 CollisionPlane = Vector4.UnitW;
4695 CollisionPlane = Vector4.UnitW;
4697 RaiseCollisionScriptEvents(coldata);
4699 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
4700 if (Invulnerable || GodLevel > 0)
4703 // The following may be better in the ICombatModule
4704 // probably tweaking of the values for ground and normal prim collisions will be needed
4705 float starthealth = Health;
4707 SceneObjectPart part = null;
4708 foreach (uint localid in coldata.Keys)
4716 part = Scene.GetSceneObjectPart(localid);
4720 // Ignore if it has been deleted or volume detect
4721 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
4723 if (part.ParentGroup.Damage > 0.0f)
4725 // Something with damage...
4726 Health -= part.ParentGroup.Damage;
4727 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
4732 if (coldata[localid].PenetrationDepth >= 0.10f)
4733 Health -= coldata[localid].PenetrationDepth * 5.0f;
4740 // what about collisions with other avatars?
4741 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
4742 Health -= coldata[localid].PenetrationDepth * 5.0f;
4749 killerObj = localid;
4751 //m_log.Debug("[AVATAR]: Collision with localid:
" + localid.ToString() + " at depth:
" + coldata[localid].ToString());
4756 if (starthealth != Health)
4758 ControllingClient.SendHealth(Health);
4762 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
4764 if (starthealth == Health && Health < 100.0f)
4767 if (Health > 100.0f)
4769 ControllingClient.SendHealth(Health);
4774 public void setHealthWithUpdate(float health)
4777 ControllingClient.SendHealth(Health);
4780 protected internal void Close()
4782 // Clear known regions
4783 KnownRegions = new Dictionary<ulong, string>();
4785 // I don't get it but mono crashes when you try to dispose of this timer,
4786 // unsetting the elapsed callback should be enough to allow for cleanup however.
4787 // m_reprioritizationTimer.Dispose();
4789 RemoveFromPhysicalScene();
4791 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4793 // if (Animator != null)
4794 // Animator.Close();
4797 LifecycleState = ScenePresenceState.Removed;
4800 public void AddAttachment(SceneObjectGroup gobj)
4802 lock (m_attachments)
4804 // This may be true when the attachment comes back
4805 // from serialization after login. Clear it.
4806 gobj.IsDeleted = false;
4808 m_attachments.Add(gobj);
4811 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
4812 if (bakedModule != null)
4813 bakedModule.UpdateMeshAvatar(m_uuid);
4820 public List<SceneObjectGroup> GetAttachments()
4822 lock (m_attachments)
4823 return new List<SceneObjectGroup>(m_attachments);
4831 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
4833 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
4835 if (attachmentPoint >= 0)
4837 lock (m_attachments)
4839 foreach (SceneObjectGroup so in m_attachments)
4841 if (attachmentPoint == so.AttachmentPoint)
4842 attachments.Add(so);
4850 public bool HasAttachments()
4852 lock (m_attachments)
4853 return m_attachments.Count > 0;
4859 public int ScriptCount()
4862 lock (m_attachments)
4864 foreach (SceneObjectGroup gobj in m_attachments)
4868 count += gobj.ScriptCount();
4878 public float ScriptExecutionTime()
4881 lock (m_attachments)
4883 foreach (SceneObjectGroup gobj in m_attachments)
4887 time += gobj.ScriptExecutionTime();
4897 public int RunningScriptCount()
4900 lock (m_attachments)
4902 foreach (SceneObjectGroup gobj in m_attachments)
4906 count += gobj.RunningScriptCount();
4913 public bool HasScriptedAttachments()
4915 lock (m_attachments)
4917 foreach (SceneObjectGroup gobj in m_attachments)
4921 if (gobj.RootPart.Inventory.ContainsScripts())
4929 public void RemoveAttachment(SceneObjectGroup gobj)
4931 lock (m_attachments)
4932 m_attachments.Remove(gobj);
4938 public void ClearAttachments()
4940 lock (m_attachments)
4941 m_attachments.Clear();
4947 public bool ValidateAttachments()
4949 bool validated = true;
4951 lock (m_attachments)
4954 foreach (SceneObjectGroup gobj in m_attachments)
4959 "[SCENE PRESENCE]: Failed to validate an attachment
for {0} since it was null. Continuing
", Name);
4963 else if (gobj.IsDeleted)
4966 "[SCENE PRESENCE]: Failed to validate attachment {0} {1}
for {2} since it had been deleted. Continuing
",
4967 gobj.Name, gobj.UUID, Name);
4977 public void SendAttachmentsToAllAgents()
4979 lock (m_attachments)
4981 foreach (SceneObjectGroup sog in m_attachments)
4983 m_scene.ForEachScenePresence(delegate(ScenePresence p)
4985 if (p != this && sog.HasPrivateAttachmentPoint)
4988 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
4991 SendTerseUpdateToAgentNF(p);
4992 SendAttachmentFullUpdateToAgentNF(sog, p);
4998 // send attachments to a client without filters except for huds
4999 // for now they are checked in several places down the line...
5000 public void SendAttachmentsToAgentNF(ScenePresence p)
5002 SendTerseUpdateToAgentNF(p);
5003 // SendAvatarDataToAgentNF(this);
5004 lock (m_attachments)
5006 foreach (SceneObjectGroup sog in m_attachments)
5008 SendAttachmentFullUpdateToAgentNF(sog, p);
5013 public void SendAttachmentFullUpdateToAgentNF(SceneObjectGroup sog, ScenePresence p)
5015 if (p != this && sog.HasPrivateAttachmentPoint)
5018 SceneObjectPart[] parts = sog.Parts;
5019 SceneObjectPart rootpart = sog.RootPart;
5021 p.ControllingClient.SendEntityUpdate(rootpart, PrimUpdateFlags.FullUpdate);
5023 for (int i = 0; i < parts.Length; i++)
5025 SceneObjectPart part = parts[i];
5026 if (part == rootpart)
5028 p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate);
5032 public void SendAttachmentScheduleUpdate(SceneObjectGroup sog)
5034 if (IsChildAgent || IsInTransit)
5037 SceneObjectPart[] origparts = sog.Parts;
5038 SceneObjectPart[] parts = new SceneObjectPart[origparts.Length];
5039 PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length];
5041 SceneObjectPart rootpart = sog.RootPart;
5042 UpdateRequired rootreq = sog.RootPart.UpdateFlag;
5045 bool allterse = true;
5046 for (int i = 0; i < origparts.Length; i++)
5048 if (origparts[i] != rootpart)
5050 switch (origparts[i].UpdateFlag)
5052 case UpdateRequired.NONE:
5055 case UpdateRequired.TERSE:
5056 flags[j] = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5057 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5058 parts[j] = origparts[i];
5062 case UpdateRequired.FULL:
5063 flags[j] = PrimUpdateFlags.FullUpdate;
5065 parts[j] = origparts[i];
5070 origparts[i].UpdateFlag = 0;
5073 if (j == 0 && rootreq == UpdateRequired.NONE)
5076 PrimUpdateFlags rootflag = PrimUpdateFlags.FullUpdate;
5078 if (rootreq != UpdateRequired.FULL && allterse)
5080 rootflag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5081 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5086 ControllingClient.SendEntityUpdate(rootpart, rootflag);
5088 for (int i = 0; i < nparts; i++)
5090 ControllingClient.SendEntityUpdate(parts[i], flags[i]);
5093 if (sog.HasPrivateAttachmentPoint)
5096 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5097 foreach (ScenePresence p in allPresences)
5102 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
5105 p.ControllingClient.SendEntityUpdate(rootpart, rootflag);
5107 for (int i = 0; i < nparts; i++)
5109 p.ControllingClient.SendEntityUpdate(parts[i], flags[i]);
5114 public void SendAttachmentUpdate(SceneObjectGroup sog, UpdateRequired UpdateFlag)
5116 if (IsChildAgent || IsInTransit)
5119 PrimUpdateFlags flag;
5122 case UpdateRequired.TERSE:
5123 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5124 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5127 case UpdateRequired.FULL:
5128 flag = PrimUpdateFlags.FullUpdate;
5135 SceneObjectPart[] parts = sog.Parts;
5136 SceneObjectPart rootpart = sog.RootPart;
5138 // rootpart.UpdateFlag = 0;
5140 ControllingClient.SendEntityUpdate(rootpart, flag);
5142 for (int i = 0; i < parts.Length; i++)
5144 SceneObjectPart part = parts[i];
5145 if (part == rootpart)
5147 ControllingClient.SendEntityUpdate(part, flag);
5148 // part.UpdateFlag = 0;
5151 if (sog.HasPrivateAttachmentPoint)
5155 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5156 foreach (ScenePresence p in allPresences)
5161 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
5164 p.ControllingClient.SendEntityUpdate(rootpart, flag);
5166 for (int i = 0; i < parts.Length; i++)
5168 SceneObjectPart part = parts[i];
5169 if (part == rootpart)
5171 p.ControllingClient.SendEntityUpdate(part, flag);
5176 public void SendAttachmentScheduleUpdate(SceneObjectPart part)
5178 if (IsChildAgent || IsInTransit)
5182 PrimUpdateFlags flag;
5183 switch (part.UpdateFlag)
5185 case UpdateRequired.TERSE:
5186 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5187 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5190 case UpdateRequired.FULL:
5191 flag = PrimUpdateFlags.FullUpdate;
5198 part.UpdateFlag = 0;
5200 ControllingClient.SendEntityUpdate(part, flag);
5202 if (part.ParentGroup.HasPrivateAttachmentPoint)
5205 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5206 foreach (ScenePresence p in allPresences)
5211 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
5214 p.ControllingClient.SendEntityUpdate(part, flag);
5219 public void SendAttachmentUpdate(SceneObjectPart part, UpdateRequired UpdateFlag)
5221 if (IsChildAgent || IsInTransit)
5224 PrimUpdateFlags flag;
5227 case UpdateRequired.TERSE:
5228 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5229 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5232 case UpdateRequired.FULL:
5233 flag = PrimUpdateFlags.FullUpdate;
5240 // part.UpdateFlag = 0;
5242 ControllingClient.SendEntityUpdate(part, flag);
5244 if (part.ParentGroup.HasPrivateAttachmentPoint)
5247 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5248 foreach (ScenePresence p in allPresences)
5252 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
5255 p.ControllingClient.SendEntityUpdate(part, flag);
5264 public void SendScriptEventToAttachments(string eventName, Object[] args)
5266 Util.FireAndForget(delegate(object x)
5268 if (m_scriptEngines.Length == 0)
5271 lock (m_attachments)
5273 foreach (SceneObjectGroup grp in m_attachments)
5275 // 16384 is CHANGED_ANIMATION
5277 // Send this to all attachment root prims
5279 foreach (IScriptModule m in m_scriptEngines)
5281 if (m == null) // No script engine loaded
5284 m.PostObjectEvent(grp.RootPart.UUID, "changed
", new Object[] { (int)Changed.ANIMATION });
5288 }, null, "ScenePresence.SendScriptEventToAttachments
");
5297 public float GetMass()
5299 PhysicsActor pa = PhysicsActor;
5307 internal void PushForce(Vector3 impulse)
5309 if (PhysicsActor != null)
5311 PhysicsActor.AddForce(impulse,true);
5315 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
5317 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
5321 ControllingClient.SendTakeControls(controls, false, false);
5322 ControllingClient.SendTakeControls(controls, true, false);
5324 ScriptControllers obj = new ScriptControllers();
5325 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
5326 obj.eventControls = ScriptControlled.CONTROL_ZERO;
5328 obj.objectID = p.ParentGroup.UUID;
5329 obj.itemID = Script_item_UUID;
5330 if (pass_on == 0 && accept == 0)
5332 IgnoredControls |= (ScriptControlled)controls;
5333 obj.ignoreControls = (ScriptControlled)controls;
5336 if (pass_on == 0 && accept == 1)
5338 IgnoredControls |= (ScriptControlled)controls;
5339 obj.ignoreControls = (ScriptControlled)controls;
5340 obj.eventControls = (ScriptControlled)controls;
5343 if (pass_on == 1 && accept == 1)
5345 IgnoredControls = ScriptControlled.CONTROL_ZERO;
5346 obj.eventControls = (ScriptControlled)controls;
5347 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
5350 lock (scriptedcontrols)
5352 if (pass_on == 1 && accept == 0)
5354 IgnoredControls &= ~(ScriptControlled)controls;
5355 if (scriptedcontrols.ContainsKey(Script_item_UUID))
5356 scriptedcontrols.Remove(Script_item_UUID);
5360 scriptedcontrols[Script_item_UUID] = obj;
5364 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
5367 public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID)
5369 IgnoredControls = ScriptControlled.CONTROL_ZERO;
5370 lock (scriptedcontrols)
5372 scriptedcontrols.Clear();
5374 ControllingClient.SendTakeControls(int.MaxValue, false, false);
5377 public void ClearControls()
5379 IgnoredControls = ScriptControlled.CONTROL_ZERO;
5380 lock (scriptedcontrols)
5382 scriptedcontrols.Clear();
5386 public void UnRegisterSeatControls(UUID obj)
5388 List<UUID> takers = new List<UUID>();
5390 foreach (ScriptControllers c in scriptedcontrols.Values)
5392 if (c.objectID == obj)
5393 takers.Add(c.itemID);
5395 foreach (UUID t in takers)
5397 UnRegisterControlEventsToScript(0, t);
5401 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
5403 ScriptControllers takecontrols;
5405 lock (scriptedcontrols)
5407 if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols))
5409 ScriptControlled sctc = takecontrols.eventControls;
5411 ControllingClient.SendTakeControls((int)sctc, false, false);
5412 ControllingClient.SendTakeControls((int)sctc, true, false);
5414 scriptedcontrols.Remove(Script_item_UUID);
5415 IgnoredControls = ScriptControlled.CONTROL_ZERO;
5416 foreach (ScriptControllers scData in scriptedcontrols.Values)
5418 IgnoredControls |= scData.ignoreControls;
5424 private void SendControlsToScripts(uint flags)
5426 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
5427 // (e.g., a walking script) checks which animation is active it will be the correct animation.
5428 lock (scriptedcontrols)
5430 if (scriptedcontrols.Count <= 0)
5433 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
5437 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
5438 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
5440 allflags = ScriptControlled.CONTROL_ZERO;
5445 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
5447 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
5451 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
5453 allflags |= ScriptControlled.CONTROL_LBUTTON;
5457 // find all activated controls, whether the scripts are interested in them or not
5458 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
5460 allflags |= ScriptControlled.CONTROL_FWD;
5463 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
5465 allflags |= ScriptControlled.CONTROL_BACK;
5468 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
5470 allflags |= ScriptControlled.CONTROL_UP;
5473 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
5475 allflags |= ScriptControlled.CONTROL_DOWN;
5478 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
5480 allflags |= ScriptControlled.CONTROL_LEFT;
5483 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
5485 allflags |= ScriptControlled.CONTROL_RIGHT;
5488 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
5490 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
5493 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
5495 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
5498 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
5499 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
5501 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
5503 UUID scriptUUID = kvp.Key;
5504 ScriptControllers scriptControlData = kvp.Value;
5506 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
5507 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
5508 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
5510 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
5512 // only send if still pressed or just changed
5513 m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange);
5518 LastCommands = allflags;
5522 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
5524 if (ignored == ScriptControlled.CONTROL_ZERO)
5527 if ((ignored & ScriptControlled.CONTROL_BACK) != 0)
5528 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
5529 if ((ignored & ScriptControlled.CONTROL_FWD) != 0)
5530 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS);
5531 if ((ignored & ScriptControlled.CONTROL_DOWN) != 0)
5532 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG);
5533 if ((ignored & ScriptControlled.CONTROL_UP) != 0)
5534 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS);
5535 if ((ignored & ScriptControlled.CONTROL_LEFT) != 0)
5536 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
5537 if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0)
5538 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG);
5539 if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0)
5540 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG);
5541 if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0)
5542 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS);
5543 if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
5544 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN);
5545 if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0)
5546 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN);
5548 //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
5549 //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
5550 //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
5551 //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
5552 //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
5553 //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
5554 //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
5559 // returns true it local teleport allowed and sets the destiny position into pos
5561 private bool CheckLocalTPLandingPoint(ref Vector3 pos)
5563 // Never constrain lures
5564 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
5567 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
5570 // do not constrain gods and estate managers
5571 if(m_scene.Permissions.IsGod(m_uuid) ||
5572 m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))
5575 // will teleport to a telehub spawn point or landpoint if that results in getting closer to target
5576 // if not the local teleport fails.
5578 float currDistanceSQ = Vector3.DistanceSquared(AbsolutePosition, pos);
5580 // first check telehub
5582 UUID TelehubObjectID = m_scene.RegionInfo.RegionSettings.TelehubObject;
5583 if ( TelehubObjectID != UUID.Zero)
5585 SceneObjectGroup telehubSOG = m_scene.GetSceneObjectGroup(TelehubObjectID);
5586 if(telehubSOG != null)
5591 SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
5592 if(spawnPoints.Length == 0)
5594 spawnPos = new Vector3(128.0f, 128.0f, pos.Z);
5595 spawnDistSQ = Vector3.DistanceSquared(spawnPos, pos);
5599 Vector3 hubPos = telehubSOG.AbsolutePosition;
5600 Quaternion hubRot = telehubSOG.GroupRotation;
5602 spawnPos = spawnPoints[0].GetLocation(hubPos, hubRot);
5603 spawnDistSQ = Vector3.DistanceSquared(spawnPos, pos);
5606 Vector3 testSpawnPos;
5607 for(int i = 1; i< spawnPoints.Length; i++)
5609 testSpawnPos = spawnPoints[i].GetLocation(hubPos, hubRot);
5610 testDistSQ = Vector3.DistanceSquared(testSpawnPos, pos);
5612 if(testDistSQ < spawnDistSQ)
5614 spawnPos = testSpawnPos;
5615 spawnDistSQ = testDistSQ;
5619 if (currDistanceSQ < spawnDistSQ)
5621 // we are already close
5622 ControllingClient.SendAlertMessage("Can
't teleport closer to destination");
5633 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
5635 if (land.LandData.LandingType != (byte)LandingType.LandingPoint
5636 || land.LandData.OwnerID == m_uuid)
5639 Vector3 landLocation = land.LandData.UserLocation;
5640 if(landLocation == Vector3.Zero)
5643 if (currDistanceSQ < Vector3.DistanceSquared(landLocation, pos))
5645 ControllingClient.SendAlertMessage("Can't teleport closer to destination
");
5649 pos = land.LandData.UserLocation;
5653 const TeleportFlags TeleHubTPFlags = TeleportFlags.ViaLogin
5654 | TeleportFlags.ViaHGLogin | TeleportFlags.ViaLocation;
5656 private bool CheckAndAdjustTelehub(SceneObjectGroup telehub, ref Vector3 pos, ref bool positionChanged)
5658 // forcing telehubs on any tp that reachs this
5659 if ((m_teleportFlags & TeleHubTPFlags) != 0 ||
5660 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )))
5663 Vector3 teleHubPosition = telehub.AbsolutePosition;
5665 SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
5666 if(spawnPoints.Length == 0)
5668 land = m_scene.LandChannel.GetLandObject(teleHubPosition.X,teleHubPosition.Y);
5671 pos = teleHubPosition;
5672 if(land.IsEitherBannedOrRestricted(UUID))
5674 positionChanged = true;
5683 bool selected = false;
5684 bool validhub = false;
5685 Vector3 spawnPosition;
5687 Quaternion teleHubRotation = telehub.GroupRotation;
5689 switch(m_scene.SpawnPointRouting)
5692 tries = spawnPoints.Length;
5693 if(tries < 3) // no much sense in random with a few points when there same can have bans
5694 goto case "sequence
";
5697 index = Util.RandomClass.Next(spawnPoints.Length - 1);
5699 spawnPosition = spawnPoints[index].GetLocation(teleHubPosition, teleHubRotation);
5700 land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
5701 if(land != null && !land.IsEitherBannedOrRestricted(UUID))
5704 } while(selected == false && --tries > 0 );
5707 goto case "sequence
";
5709 pos = spawnPosition;
5713 tries = spawnPoints.Length;
5718 index = m_scene.SpawnPoint();
5719 spawnPosition = spawnPoints[index].GetLocation(teleHubPosition, teleHubRotation);
5720 land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
5724 if(land.IsEitherBannedOrRestricted(UUID))
5730 } while(selected == false && --tries > 0);
5735 pos = spawnPosition;
5739 positionChanged = true;
5744 float distancesq = float.MaxValue;
5748 for(int i = 0; i < spawnPoints.Length; i++)
5750 spawnPosition = spawnPoints[i].GetLocation(teleHubPosition, teleHubRotation);
5751 Vector3 offset = spawnPosition - pos;
5752 float dsq = offset.LengthSquared();
5753 land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
5758 if(land.IsEitherBannedOrRestricted(UUID))
5761 if(dsq >= distancesq)
5772 pos = spawnPoints[0].GetLocation(teleHubPosition, teleHubRotation);
5773 positionChanged = true;
5777 pos = spawnPoints[closest].GetLocation(teleHubPosition, teleHubRotation);
5778 positionChanged = true;
5785 const TeleportFlags adicionalLandPointFlags = TeleportFlags.ViaLandmark |
5786 TeleportFlags.ViaLocation | TeleportFlags.ViaHGLogin;
5788 // Modify landing point based on telehubs or parcel restrictions.
5789 private bool CheckAndAdjustLandingPoint(ref Vector3 pos, ref Vector3 lookat, ref bool positionChanged)
5793 // dont mess with gods
5794 if(GodLevel >= 200 || m_scene.Permissions.IsGod(m_uuid))
5797 // respect region owner and managers
5798 // if(m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))
5801 if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
5803 SceneObjectGroup telehub = null;
5804 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
5806 if(CheckAndAdjustTelehub(telehub, ref pos, ref positionChanged))
5811 // Honor bans, actually we don't honour them
5812 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
5815 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
5818 if (Scene.DebugTeleporting)
5819 TeleportFlagsDebug();
5821 // If we come in via login, landmark or map, we want to
5822 // honor landing points. If we come in via Lure, we want
5824 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
5825 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)
5826 || (m_teleportFlags & adicionalLandPointFlags) != 0)
5828 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
5829 land.LandData.UserLocation != Vector3.Zero )
5831 // land.LandData.OwnerID != m_uuid )
5833 pos = land.LandData.UserLocation;
5834 if(land.LandData.UserLookAt != Vector3.Zero)
5835 lookat = land.LandData.UserLookAt;
5836 positionChanged = true;
5843 private DetectedObject CreateDetObject(SceneObjectPart obj)
5845 DetectedObject detobj = new DetectedObject();
5846 detobj.keyUUID = obj.UUID;
5847 detobj.nameStr = obj.Name;
5848 detobj.ownerUUID = obj.OwnerID;
5849 detobj.posVector = obj.AbsolutePosition;
5850 detobj.rotQuat = obj.GetWorldRotation();
5851 detobj.velVector = obj.Velocity;
5852 detobj.colliderType = 0;
5853 detobj.groupUUID = obj.GroupID;
5854 detobj.linkNumber = 0;
5859 private DetectedObject CreateDetObject(ScenePresence av)
5861 DetectedObject detobj = new DetectedObject();
5862 detobj.keyUUID = av.UUID;
5863 detobj.nameStr = av.ControllingClient.Name;
5864 detobj.ownerUUID = av.UUID;
5865 detobj.posVector = av.AbsolutePosition;
5866 detobj.rotQuat = av.Rotation;
5867 detobj.velVector = av.Velocity;
5868 detobj.colliderType = 0;
5869 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
5870 detobj.linkNumber = 0;
5875 private DetectedObject CreateDetObjectForGround()
5877 DetectedObject detobj = new DetectedObject();
5878 detobj.keyUUID = UUID.Zero;
5879 detobj.nameStr = "";
5880 detobj.ownerUUID = UUID.Zero;
5881 detobj.posVector = AbsolutePosition;
5882 detobj.rotQuat = Quaternion.Identity;
5883 detobj.velVector = Vector3.Zero;
5884 detobj.colliderType = 0;
5885 detobj.groupUUID = UUID.Zero;
5886 detobj.linkNumber = 0;
5890 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
5892 ColliderArgs colliderArgs = new ColliderArgs();
5893 List<DetectedObject> colliding = new List<DetectedObject>();
5894 foreach (uint localId in colliders)
5899 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
5902 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
5903 colliding.Add(CreateDetObject(obj));
5907 ScenePresence av = m_scene.GetScenePresence(localId);
5908 if (av != null && (!av.IsChildAgent))
5910 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
5911 colliding.Add(CreateDetObject(av));
5916 colliderArgs.Colliders = colliding;
5918 return colliderArgs;
5921 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
5923 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
5925 ColliderArgs CollidingMessage;
5927 if (colliders.Count > 0)
5929 if ((dest.RootPart.ScriptEvents & ev) != 0)
5931 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
5933 if (CollidingMessage.Colliders.Count > 0)
5934 notify(dest.RootPart.LocalId, CollidingMessage);
5939 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
5941 if ((dest.RootPart.ScriptEvents & ev) != 0)
5943 ColliderArgs LandCollidingMessage = new ColliderArgs();
5944 List<DetectedObject> colliding = new List<DetectedObject>();
5946 colliding.Add(CreateDetObjectForGround());
5947 LandCollidingMessage.Colliders = colliding;
5949 notify(dest.RootPart.LocalId, LandCollidingMessage);
5953 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
5957 List<uint> thisHitColliders = new List<uint>();
5958 List<uint> endedColliders = new List<uint>();
5959 List<uint> startedColliders = new List<uint>();
5960 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
5961 CollisionForSoundInfo soundinfo;
5962 ContactPoint curcontact;
5964 if (coldata.Count == 0)
5966 if (m_lastColliders.Count == 0)
5967 return; // nothing to do
5969 foreach (uint localID in m_lastColliders)
5971 endedColliders.Add(localID);
5973 m_lastColliders.Clear();
5978 bool candoparcelSound = ParcelAllowThisAvatarSounds;
5980 foreach (uint id in coldata.Keys)
5982 thisHitColliders.Add(id);
5983 if (!m_lastColliders.Contains(id))
5985 startedColliders.Add(id);
5986 curcontact = coldata[id];
5987 if (candoparcelSound && Math.Abs(curcontact.RelativeSpeed) > 0.2)
5989 soundinfo = new CollisionForSoundInfo();
5990 soundinfo.colliderID = id;
5991 soundinfo.position = curcontact.Position;
5992 soundinfo.relativeVel = curcontact.RelativeSpeed;
5993 soundinfolist.Add(soundinfo);
5996 //m_log.Debug("[SCENE PRESENCE]: Collided with:
" + localid.ToString() + " at depth of:
" + collissionswith[localid].ToString());
5999 // calculate things that ended colliding
6000 foreach (uint localID in m_lastColliders)
6002 if (!thisHitColliders.Contains(localID))
6004 endedColliders.Add(localID);
6007 //add the items that started colliding this time to the last colliders list.
6008 foreach (uint localID in startedColliders)
6010 m_lastColliders.Add(localID);
6012 // remove things that ended colliding from the last colliders list
6013 foreach (uint localID in endedColliders)
6015 m_lastColliders.Remove(localID);
6018 if (soundinfolist.Count > 0)
6019 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
6022 foreach (SceneObjectGroup att in GetAttachments())
6024 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
6025 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
6026 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
6028 if (startedColliders.Contains(0))
6029 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
6030 if (m_lastColliders.Contains(0))
6031 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
6032 if (endedColliders.Contains(0))
6033 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
6039 // m_collisionEventFlag = false;
6043 private void TeleportFlagsDebug() {
6045 // Some temporary debugging help to show all the TeleportFlags we have...
6047 if((m_teleportFlags & TeleportFlags.ViaHGLogin) == TeleportFlags.ViaHGLogin)
6050 m_log.InfoFormat("[SCENE PRESENCE]:
TELEPORT ******************
");
6053 for (int x = 0; x <= 30 ; x++, i = 1u << x)
6057 if((m_teleportFlags & (TeleportFlags)i) == (TeleportFlags)i)
6059 m_log.InfoFormat("[SCENE PRESENCE]: Teleport Flags include {0}
", ((TeleportFlags) i).ToString());
6061 m_log.InfoFormat("[SCENE PRESENCE]: HG Teleport Flags include {0}
", ((TeleportFlags)i).ToString());
6064 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************
");
6068 private void parcelGodCheck(UUID currentParcelID, bool isGod)
6070 List<ScenePresence> allpresences = m_scene.GetScenePresences();
6072 foreach (ScenePresence p in allpresences)
6074 if (p.IsDeleted || p.IsChildAgent || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6077 if (p.ParcelHideThisAvatar && p.currentParcelUUID != currentParcelID)
6087 private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID,
6088 bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check)
6090 List<ScenePresence> killsToSendto = new List<ScenePresence>();
6091 List<ScenePresence> killsToSendme = new List<ScenePresence>();
6092 List<ScenePresence> viewsToSendto = new List<ScenePresence>();
6093 List<ScenePresence> viewsToSendme = new List<ScenePresence>();
6094 List<ScenePresence> allpresences = null;
6096 if (IsInTransit || IsChildAgent)
6101 // check is relative to current parcel only
6102 if (currentParcelUUID == null || oldhide == currentParcelHide)
6105 allpresences = m_scene.GetScenePresences();
6109 foreach (ScenePresence p in allpresences)
6111 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6114 // those on not on parcel see me
6115 if (currentParcelID != p.currentParcelUUID)
6117 viewsToSendto.Add(p); // they see me
6120 } // where private end
6124 foreach (ScenePresence p in allpresences)
6126 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6129 // those not on parcel dont see me
6130 if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200)
6132 killsToSendto.Add(p); // they dont see me
6135 } // where public end
6137 allpresences.Clear();
6141 if (currentParcelHide)
6143 // now on a private parcel
6144 allpresences = m_scene.GetScenePresences();
6146 if (previusParcelHide && previusParcelID != UUID.Zero)
6148 foreach (ScenePresence p in allpresences)
6150 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6153 // only those on previus parcel need receive kills
6154 if (previusParcelID == p.currentParcelUUID)
6156 if(p.GodLevel < 200)
6157 killsToSendto.Add(p); // they dont see me
6159 killsToSendme.Add(p); // i dont see them
6161 // only those on new parcel need see
6162 if (currentParcelID == p.currentParcelUUID)
6164 viewsToSendto.Add(p); // they see me
6165 viewsToSendme.Add(p); // i see them
6171 //was on a public area
6172 allpresences = m_scene.GetScenePresences();
6174 foreach (ScenePresence p in allpresences)
6176 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6179 // those not on new parcel dont see me
6180 if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200)
6182 killsToSendto.Add(p); // they dont see me
6186 viewsToSendme.Add(p); // i see those on it
6190 allpresences.Clear();
6191 } // now on a private parcel end
6195 // now on public parcel
6196 if (previusParcelHide && previusParcelID != UUID.Zero)
6198 // was on private area
6199 allpresences = m_scene.GetScenePresences();
6201 foreach (ScenePresence p in allpresences)
6203 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6205 // only those old parcel need kills
6206 if (previusParcelID == p.currentParcelUUID && GodLevel < 200)
6208 killsToSendme.Add(p); // i dont see them
6212 viewsToSendto.Add(p); // they see me
6217 return; // was on a public area also
6218 } // now on public parcel end
6223 if (killsToSendto.Count > 0)
6225 foreach (ScenePresence p in killsToSendto)
6227 // m_log.Debug("[AVATAR]: killTo:
" + Lastname + " " + p.Lastname);
6232 if (killsToSendme.Count > 0)
6234 foreach (ScenePresence p in killsToSendme)
6236 // m_log.Debug("[AVATAR]: killToMe:
" + Lastname + " " + p.Lastname);
6241 if (viewsToSendto.Count > 0)
6243 foreach (ScenePresence p in viewsToSendto)
6249 if (viewsToSendme.Count > 0 )
6251 foreach (ScenePresence p in viewsToSendme)
6255 // m_log.Debug("[AVATAR]: viewMe:
" + Lastname + "<-
" + p.Lastname);
6261 public void HasMovedAway(bool nearRegion)
6266 if (Scene.AttachmentsModule != null)
6267 Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true);
6269 if (!ParcelHideThisAvatar || GodLevel >= 200)
6272 List<ScenePresence> allpresences = m_scene.GetScenePresences();
6273 foreach (ScenePresence p in allpresences)
6275 if (p.IsDeleted || p == this || p.IsChildAgent || p.ControllingClient == null || !p.ControllingClient.IsActive)
6278 if (p.currentParcelUUID == m_currentParcelUUID)
6286 List<ScenePresence> allpresences = m_scene.GetScenePresences();
6287 foreach (ScenePresence p in allpresences)
6292 if (!p.IsChildAgent)
6296 if (Scene.AttachmentsModule != null)
6297 Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true);
6302 // kill with attachs root kills
6303 public void SendKillTo(ScenePresence p)
6305 List<uint> ids = new List<uint>(m_attachments.Count + 1);
6306 foreach (SceneObjectGroup sog in m_attachments)
6308 ids.Add(sog.RootPart.LocalId);
6312 p.ControllingClient.SendKillObject(ids);
6317 public void SendKillTo(ScenePresence p)
6319 foreach (SceneObjectGroup sog in m_attachments)
6320 p.ControllingClient.SendPartFullUpdate(sog.RootPart, LocalId + 1);
6321 p.ControllingClient.SendKillObject(new List<uint> { LocalId });
6324 public void SendViewTo(ScenePresence p)
6326 SendAvatarDataToAgentNF(p);
6327 SendAppearanceToAgent(p);
6328 if (Animator != null)
6329 Animator.SendAnimPackToClient(p.ControllingClient);
6330 SendAttachmentsToAgentNF(p);
6333 public void SetAnimationOverride(string animState, UUID animID)
6335 Overrides.SetOverride(animState, animID);
6336 // Animator.SendAnimPack();
6337 Animator.ForceUpdateMovementAnimations();
6340 public UUID GetAnimationOverride(string animState)
6342 return Overrides.GetOverriddenAnimation(animState);
int GetStateSource()
Force viewers to show the avatar's current name.
void TeleportWithMomentum(Vector3 pos, Vector3?v)
OpenSim.Framework.Constants.TeleportFlags TeleportFlags
void RemoveFromPhysicalScene()
Removes physics plugin scene representation of this agent if it exists.
OpenSim.Framework.Constants.TeleportFlags TeleportFlags
AvatarAppearance m_appearance
void DropOldNeighbours(List< ulong > oldRegions)
ScenePresence(IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
Contains the Avatar's Appearance and methods to manipulate the appearance.
delegate void SendCoarseLocationsMethod(UUID scene, ScenePresence presence, List< Vector3 > coarseLocations, List< UUID > avatarUUIDs)
void TriggerScenePresenceUpdated()
Vector3 m_reprioritizationLastPosition
ScenePresenceState
The possible states that a scene presence can be in. This is currently orthagonal to whether a scene ...
bool sentMessageAboutRestrictedParcelFlyingDown
delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun)
void avnLocalTeleport(Vector3 newpos, Vector3?newvel, bool rotateToVelXY)
void DropThisRootRegionFromNeighbours()
Handle all animation duties for a scene presence
void RemoveNeighbourRegion(ulong regionHandle)
Vector3 lastKnownAllowedPosition
System.Timers.Timer Timer
PresenceType
Indicate the type of ScenePresence.
System.Timers.Timer Timer
bool m_reprioritizationBusy
void Teleport(Vector3 pos)
Do not call this directly. Call Scene.RequestTeleportLocation() instead.
int m_reprioritizationLastTime
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
ICapabilitiesModule CapsModule
ScriptControlled ignoreControls
void MakeChildAgent(ulong newRegionHandle)
This turns a root agent into a child agent
Vector3 GetWorldVelocity()
Get velocity relative to the world.
ScriptControlled eventControls
void SetNeighbourRegionSizeInfo(List< GridRegion > regionsList)
OpenSim.Framework.Animation Animation
void SetSize(Vector3 size, float feetoffset)
Quaternion GetWorldRotation()
Gets the world rotation of this presence.
uint teleportFlags
How this agent got here
void AddNeighbourRegionSizeInfo(GridRegion region)
OpenSim.Services.Interfaces.GridRegion GridRegion
void SetHeight(float height)
Sets avatar height in the physics plugin
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3 vector